Skip to content

Commit

Permalink
fix(test): clobber libxml2's global error handler before every test
Browse files Browse the repository at this point in the history
to check that we're setting error handlers everywhere we need to.

Related to #2168
  • Loading branch information
flavorjones committed Jan 6, 2021
1 parent b682ac5 commit 07459fd
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ext/nokogiri/nokogiri.c
@@ -1,5 +1,7 @@
#include <nokogiri.h>

void init_test_global_handlers(); /* in lieu of test_global_handlers.h */

VALUE mNokogiri ;
VALUE mNokogiriXml ;
VALUE mNokogiriHtml ;
Expand Down Expand Up @@ -132,4 +134,5 @@ void Init_nokogiri()
init_xml_relax_ng();
init_nokogiri_io();
init_xml_encoding_handler();
init_test_global_handlers();
}
41 changes: 41 additions & 0 deletions ext/nokogiri/test_global_handlers.c
@@ -0,0 +1,41 @@
#include <nokogiri.h>
#include "libxml/xmlerror.h"

static VALUE foreign_error_handler_block = Qnil;

static void foreign_error_handler(void* user_data, xmlErrorPtr c_error)
{
rb_funcall(foreign_error_handler_block, rb_intern("call"), 0);
}

/*
* call-seq:
* __foreign_error_handler { ... } -> nil
*
* Override libxml2's global error handlers to call the block. This method thus has very little
* value except to test that Nokogiri is properly setting error handlers elsewhere in the code. See
* test/helper.rb for how this is being used.
*/
static VALUE
rb_foreign_error_handler(VALUE klass)
{
rb_need_block();
foreign_error_handler_block = rb_block_proc();
xmlSetStructuredErrorFunc(NULL, foreign_error_handler);
return Qnil;
}

/*
* Document-module: Nokogiri::Test
*
* The Nokogiri::Test module should only be used for testing Nokogiri.
* Do NOT use this outside of the Nokogiri test suite.
*/
void
init_test_global_handlers()
{
VALUE mNokogiri = rb_define_module("Nokogiri");
VALUE mNokogiriTest = rb_define_module_under(mNokogiri, "Test");

rb_define_singleton_method(mNokogiriTest, "__foreign_error_handler", rb_foreign_error_handler, 0);
}
14 changes: 14 additions & 0 deletions test/helper.rb
Expand Up @@ -58,7 +58,16 @@ class TestCase < MiniTest::Spec
XSLT_FILE = File.join(ASSETS_DIR, 'staff.xslt')
XPATH_FILE = File.join(ASSETS_DIR, 'slow-xpath.xml')

def setup
@fake_error_handler_called = false
Nokogiri::Test.__foreign_error_handler do
@fake_error_handler_called = true
end if Nokogiri.uses_libxml?
end

def teardown
refute(@fake_error_handler_called, "the fake error handler should never get called") if Nokogiri.uses_libxml?

if ENV['NOKOGIRI_GC']
STDOUT.putc '!'
if RUBY_PLATFORM =~ /java/
Expand Down Expand Up @@ -135,6 +144,11 @@ class Doc < XML::SAX::Document
attr_reader :xmldecls
attr_reader :processing_instructions

def initialize
@errors = []
super
end

def xmldecl version, encoding, standalone
@xmldecls = [version, encoding, standalone].compact
super
Expand Down

0 comments on commit 07459fd

Please sign in to comment.