Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ext/java/org/jruby/ext/psych/PsychParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,16 @@ private static StreamReader readerForString(ThreadContext context, RubyString st
public IRubyObject parse(ThreadContext context, IRubyObject handler, IRubyObject yaml, IRubyObject path) {
Ruby runtime = context.runtime;

// The parser calls back into Ruby for every event, so a handler can call
// Psych::Parser#parse again on the same object, which would replace the
// parser the loop below is still driving.
if (parsing) {
throw runtime.newRaiseException(
(RubyClass) runtime.getModule("Psych").getConstant("Exception"),
"parser is already parsing, it cannot be reused from a handler callback");
}
parsing = true;

try {
LoadSettings loadSettings = loadSettingsBuilder.build();
parser = new ParserImpl(loadSettings, new ScannerImpl(loadSettings, readerFor(context, yaml, loadSettings)));
Expand Down Expand Up @@ -324,6 +334,8 @@ public IRubyObject parse(ThreadContext context, IRubyObject handler, IRubyObject
} catch (Throwable t) {
Helpers.throwException(t);
return this;
} finally {
parsing = false;
}

return this;
Expand Down Expand Up @@ -567,6 +579,7 @@ private LoadSettings buildSettings() {

private Parser parser;
private Event event;
private boolean parsing;
private final LoadSettingsBuilder loadSettingsBuilder;
private final CallSites sites;

Expand Down
4 changes: 0 additions & 4 deletions test/psych/test_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ def event_location start_line, start_column, end_line, end_column
end

def test_parse_is_not_reentrant
pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/

handler = ReentrantHandler.new
handler.inner_yaml = "--- inner\n"
parser = Psych::Parser.new handler
Expand All @@ -139,8 +137,6 @@ def test_parse_is_not_reentrant
end

def test_parse_is_not_reentrant_with_invalid_inner_document
pend "Failing on JRuby" if RUBY_PLATFORM =~ /java/

handler = ReentrantHandler.new
handler.inner_yaml = "--- \x00bad\n"
parser = Psych::Parser.new handler
Expand Down