From d5e129f2162f14bdbfdc367be0914625db674ba8 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Wed, 12 Oct 2022 18:45:07 +0200 Subject: [PATCH] Upstream truffleruby patches needed when using system libraries * Adapt tests for that configuration. --- ext/nokogiri/nokogiri.h | 3 +++ ext/nokogiri/xml_sax_parser.c | 12 ++++++++++++ ext/nokogiri/xml_xpath_context.c | 17 +++++++++++++++++ ext/nokogiri/xslt_stylesheet.c | 6 ++++++ test/helper.rb | 4 ++++ test/test_xslt_transforms.rb | 13 +++++++++---- test/xml/sax/test_parser.rb | 6 +++++- test/xml/test_entity_reference.rb | 12 ++++++++++-- 8 files changed, 66 insertions(+), 7 deletions(-) diff --git a/ext/nokogiri/nokogiri.h b/ext/nokogiri/nokogiri.h index 63549ecec54..9e7918cd4d8 100644 --- a/ext/nokogiri/nokogiri.h +++ b/ext/nokogiri/nokogiri.h @@ -99,6 +99,9 @@ xmlNodePtr xmlLastElementChild(xmlNodePtr parent); # endif #endif +#if defined(TRUFFLERUBY) && !defined(NOKOGIRI_PACKAGED_LIBRARIES) +# define TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES +#endif NOKOPUBVAR VALUE mNokogiri ; NOKOPUBVAR VALUE mNokogiriGumbo ; diff --git a/ext/nokogiri/xml_sax_parser.c b/ext/nokogiri/xml_sax_parser.c index 904d8d305ac..ea772443f36 100644 --- a/ext/nokogiri/xml_sax_parser.c +++ b/ext/nokogiri/xml_sax_parser.c @@ -203,10 +203,16 @@ warning_func(void *ctx, const char *msg, ...) VALUE doc = rb_iv_get(self, "@document"); VALUE rb_message; +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + rb_message = rb_sprintf("warning_func: %s", msg); +#else va_list args; va_start(args, msg); rb_message = rb_vsprintf(msg, args); va_end(args); +#endif rb_funcall(doc, id_warning, 1, rb_message); } @@ -219,10 +225,16 @@ error_func(void *ctx, const char *msg, ...) VALUE doc = rb_iv_get(self, "@document"); VALUE rb_message; +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + rb_message = rb_sprintf("error_func: %s", msg); +#else va_list args; va_start(args, msg); rb_message = rb_vsprintf(msg, args); va_end(args); +#endif rb_funcall(doc, id_error, 1, rb_message); } diff --git a/ext/nokogiri/xml_xpath_context.c b/ext/nokogiri/xml_xpath_context.c index b8eb6338829..cb6b6574613 100644 --- a/ext/nokogiri/xml_xpath_context.c +++ b/ext/nokogiri/xml_xpath_context.c @@ -298,10 +298,16 @@ xpath_generic_exception_handler(void *ctx, const char *msg, ...) { VALUE rb_message; +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + rb_message = rb_sprintf("xpath_generic_exception_handler: %s", msg); +#else va_list args; va_start(args, msg); rb_message = rb_vsprintf(msg, args); va_end(args); +#endif rb_exc_raise(rb_exc_new3(rb_eRuntimeError, rb_message)); } @@ -336,7 +342,12 @@ evaluate(int argc, VALUE *argv, VALUE self) } xmlResetLastError(); +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + VALUE errors = rb_ary_new(); + xmlSetStructuredErrorFunc(errors, Nokogiri_error_array_pusher); +#else xmlSetStructuredErrorFunc(NULL, Nokogiri_error_raise); +#endif /* For some reason, xmlXPathEvalExpression will blow up with a generic error */ /* when there is a non existent function. */ @@ -346,6 +357,12 @@ evaluate(int argc, VALUE *argv, VALUE self) xmlSetStructuredErrorFunc(NULL, NULL); xmlSetGenericErrorFunc(NULL, NULL); +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + if (RARRAY_LEN(errors) > 0) { + rb_exc_raise(rb_ary_entry(errors, 0)); + } +#endif + if (xpath == NULL) { xmlErrorPtr error = xmlGetLastError(); rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error)); diff --git a/ext/nokogiri/xslt_stylesheet.c b/ext/nokogiri/xslt_stylesheet.c index d81a98124a6..036bc8ef8db 100644 --- a/ext/nokogiri/xslt_stylesheet.c +++ b/ext/nokogiri/xslt_stylesheet.c @@ -26,10 +26,16 @@ xslt_generic_error_handler(void *ctx, const char *msg, ...) { VALUE message; +#ifdef TRUFFLERUBY_NOKOGIRI_SYSTEM_LIBRARIES + /* It is not currently possible to pass var args from native + functions to sulong, so we work around the issue here. */ + message = rb_sprintf("xslt_generic_error_handler: %s", msg); +#else va_list args; va_start(args, msg); message = rb_vsprintf(msg, args); va_end(args); +#endif rb_str_concat((VALUE)ctx, message); } diff --git a/test/helper.rb b/test/helper.rb index 002bcd6a505..44e0c981cdc 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -119,6 +119,10 @@ def skip_unless_libxml2_patch(patch_name) def skip_unless_jruby(msg = "this test should only run with jruby") skip(msg) unless Nokogiri.jruby? end + + def truffleruby_system_libraries? + RUBY_ENGINE == "truffleruby" and !Nokogiri::PACKAGED_LIBRARIES + end end class TestBenchmark < Minitest::BenchSpec diff --git a/test/test_xslt_transforms.rb b/test/test_xslt_transforms.rb index 6c75b7d15c9..060edc79400 100644 --- a/test/test_xslt_transforms.rb +++ b/test/test_xslt_transforms.rb @@ -349,10 +349,15 @@ def test_non_html_xslt_transform exception = assert_raises(RuntimeError) do xslt.transform(doc) end - assert_match( - /xmlXPathCompOpEval: function decimal not found|java.lang.NoSuchMethodException.*decimal/, - exception.message, - ) + if truffleruby_system_libraries? + assert_equal( + "xslt_generic_error_handler: xmlXPathCompOpEval: function %s not found\nxslt_generic_error_handler: %s", + exception.message) + else + assert_match( + /xmlXPathCompOpEval: function decimal not found|java.lang.NoSuchMethodException.*decimal/, + exception.message) + end end describe "DEFAULT_XSLT parse options" do diff --git a/test/xml/sax/test_parser.rb b/test/xml/sax/test_parser.rb index 9bf9bfeeb82..7aa6c05f29c 100644 --- a/test/xml/sax/test_parser.rb +++ b/test/xml/sax/test_parser.rb @@ -484,7 +484,11 @@ def call_parse_io_with_encoding(encoding) XML parser.parse(xml) refute_empty(parser.document.warnings) - assert_match(/URI .* is not absolute/, parser.document.warnings.first) + if truffleruby_system_libraries? + assert_equal('warning_func: %s', parser.document.warnings.first) + else + assert_match(/URI .* is not absolute/, parser.document.warnings.first) + end end end end diff --git a/test/xml/test_entity_reference.rb b/test/xml/test_entity_reference.rb index 998896cf119..8b147110288 100644 --- a/test/xml/test_entity_reference.rb +++ b/test/xml/test_entity_reference.rb @@ -193,7 +193,11 @@ def setup html = File.read(xml_document) @parser.parse(html) refute_nil @parser.document.errors - assert_equal ["Entity 'bar' not defined"], @parser.document.errors.map(&:to_s).map(&:strip) + if truffleruby_system_libraries? + assert_equal ["error_func: %s"], @parser.document.errors.map(&:to_s).map(&:strip) + else + assert_equal ["Entity 'bar' not defined"], @parser.document.errors.map(&:to_s).map(&:strip) + end end test_relative_and_absolute_path :test_more_sax_entity_reference do @@ -206,7 +210,11 @@ def setup ] @parser.parse(html) refute_nil @parser.document.errors - assert_equal ["Entity 'bar' not defined"], @parser.document.errors.map(&:to_s).map(&:strip) + if truffleruby_system_libraries? + assert_equal ["error_func: %s"], @parser.document.errors.map(&:to_s).map(&:strip) + else + assert_equal ["Entity 'bar' not defined"], @parser.document.errors.map(&:to_s).map(&:strip) + end end end