From d2f5e1d18040ddfa6a4e7f746b29d4d8a78c3ebf Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 25 Feb 2021 12:32:49 -0600 Subject: Negotiate to utf-8 in scalar --- ext/java/org/jruby/ext/psych/PsychEmitter.java | 40 ++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'ext') diff --git a/ext/java/org/jruby/ext/psych/PsychEmitter.java b/ext/java/org/jruby/ext/psych/PsychEmitter.java index 1372c2f..ecaf2e5 100644 --- a/ext/java/org/jruby/ext/psych/PsychEmitter.java +++ b/ext/java/org/jruby/ext/psych/PsychEmitter.java @@ -29,11 +29,13 @@ package org.jruby.ext.psych; import java.io.IOException; import java.io.OutputStreamWriter; +import java.io.Writer; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import org.jcodings.Encoding; +import org.jcodings.specific.UTF8Encoding; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; @@ -46,6 +48,8 @@ import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.IOOutputStream; +import org.jruby.util.TypeConverter; +import org.jruby.util.io.EncodingUtils; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.emitter.Emitter; import org.yaml.snakeyaml.emitter.EmitterException; @@ -189,21 +193,41 @@ public class PsychEmitter extends RubyObject { IRubyObject plain = args[3]; IRubyObject quoted = args[4]; IRubyObject style = args[5]; - - if (!(value instanceof RubyString)) { - throw context.runtime.newTypeError(value, context.runtime.getString()); + + RubyClass stringClass = context.runtime.getString(); + + TypeConverter.checkType(context, value, stringClass); + + RubyString valueStr = (RubyString) value; + Encoding encoding = UTF8Encoding.INSTANCE; + + valueStr = EncodingUtils.strConvEnc(context, valueStr, valueStr.getEncoding(), encoding); + + RubyString anchorStr = null; + if (!anchor.isNil()) { + TypeConverter.checkType(context, anchor, stringClass); + anchorStr = (RubyString) anchor; + anchorStr = EncodingUtils.strConvEnc(context, anchorStr, anchorStr.getEncoding(), encoding); + } + + RubyString tagStr = null; + if (!tag.isNil()) { + TypeConverter.checkType(context, tag, stringClass); + tagStr = (RubyString) tag; + tagStr = EncodingUtils.strConvEnc(context, tagStr, tagStr.getEncoding(), encoding); } ScalarEvent event = new ScalarEvent( - anchor.isNil() ? null : anchor.asJavaString(), - tag.isNil() ? null : tag.asJavaString(), - new ImplicitTuple(plain.isTrue(), - quoted.isTrue()), - value.asJavaString(), + anchorStr == null ? null : anchorStr.asJavaString(), + tagStr == null ? null : tagStr.asJavaString(), + new ImplicitTuple(plain.isTrue(), quoted.isTrue()), + valueStr.asJavaString(), NULL_MARK, NULL_MARK, SCALAR_STYLES[style.convertToInteger().getIntValue()]); + emit(context, event); + return this; } -- cgit v1.2.1 From 5d734aab8fad9d42b80bff3ba0a76254c3509a66 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 25 Feb 2021 14:34:11 -0600 Subject: Flush writer after each emit OutputStreamWriter from JDK buffers outgoing bytes with a 8k buffer, which causes some small document emits to never make it into the outgoing stream unless that stream gets flushed or closed. --- ext/java/org/jruby/ext/psych/PsychEmitter.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ext') diff --git a/ext/java/org/jruby/ext/psych/PsychEmitter.java b/ext/java/org/jruby/ext/psych/PsychEmitter.java index ecaf2e5..ec71b93 100644 --- a/ext/java/org/jruby/ext/psych/PsychEmitter.java +++ b/ext/java/org/jruby/ext/psych/PsychEmitter.java @@ -336,6 +336,9 @@ public class PsychEmitter extends RubyObject { if (emitter == null) throw context.runtime.newRuntimeError("uninitialized emitter"); emitter.emit(event); + + // flush writer after each emit + writer.flush(); } catch (IOException ioe) { throw context.runtime.newIOErrorFromException(ioe); } catch (EmitterException ee) { @@ -349,10 +352,12 @@ public class PsychEmitter extends RubyObject { Encoding encoding = PsychLibrary.YAMLEncoding.values()[(int)_encoding.convertToInteger().getLongValue()].encoding; Charset charset = context.runtime.getEncodingService().charsetForEncoding(encoding); - emitter = new Emitter(new OutputStreamWriter(new IOOutputStream(io, encoding), charset), options); + writer = new OutputStreamWriter(new IOOutputStream(io, encoding), charset); + emitter = new Emitter(writer, options); } Emitter emitter; + Writer writer; DumperOptions options = new DumperOptions(); IRubyObject io; -- cgit v1.2.1 From b4b5b498475fc108ec157db5e07ba4ef09ae06e9 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 25 Feb 2021 15:15:47 -0600 Subject: Skip deprecated require form --- ext/java/org/jruby/ext/psych/PsychParser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ext') diff --git a/ext/java/org/jruby/ext/psych/PsychParser.java b/ext/java/org/jruby/ext/psych/PsychParser.java index b660a0f..7672cd2 100644 --- a/ext/java/org/jruby/ext/psych/PsychParser.java +++ b/ext/java/org/jruby/ext/psych/PsychParser.java @@ -89,8 +89,7 @@ public class PsychParser extends RubyObject { } }, psych); - RubyKernel.require(runtime.getNil(), - runtime.newString("psych/syntax_error"), Block.NULL_BLOCK); + runtime.getLoadService().require("psych/syntax_error"); psychParser.defineConstant("ANY", runtime.newFixnum(YAML_ANY_ENCODING.ordinal())); psychParser.defineConstant("UTF8", runtime.newFixnum(YAML_UTF8_ENCODING.ordinal())); psychParser.defineConstant("UTF16LE", runtime.newFixnum(YAML_UTF16LE_ENCODING.ordinal())); -- cgit v1.2.1 From dce46b15a52dd9e6d81a54ca70869791679c5112 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 25 Feb 2021 15:50:06 -0600 Subject: Make malformed input noisy parse should reject input encoded incorrectly. The default behavior for InputStreamReader is to replace malformed characters, which causes one exception-expecting test to fail. This patch changes the behavior to report malformed input, which can then be reraised as a syntax error. --- ext/java/org/jruby/ext/psych/PsychParser.java | 47 ++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'ext') diff --git a/ext/java/org/jruby/ext/psych/PsychParser.java b/ext/java/org/jruby/ext/psych/PsychParser.java index 7672cd2..3bc4a44 100644 --- a/ext/java/org/jruby/ext/psych/PsychParser.java +++ b/ext/java/org/jruby/ext/psych/PsychParser.java @@ -30,6 +30,9 @@ package org.jruby.ext.psych; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.MalformedInputException; import java.util.Map; import org.jcodings.Encoding; @@ -61,6 +64,7 @@ import org.jruby.util.log.LoggerFactory; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.error.Mark; import org.yaml.snakeyaml.error.MarkedYAMLException; +import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.events.AliasEvent; import org.yaml.snakeyaml.events.DocumentEndEvent; import org.yaml.snakeyaml.events.DocumentStartEvent; @@ -75,6 +79,8 @@ import org.yaml.snakeyaml.parser.ParserImpl; import org.yaml.snakeyaml.reader.ReaderException; import org.yaml.snakeyaml.reader.StreamReader; import org.yaml.snakeyaml.scanner.ScannerException; + +import static org.jruby.runtime.Helpers.arrayOf; import static org.jruby.runtime.Helpers.invoke; import org.jruby.util.ByteList; @@ -174,7 +180,11 @@ public class PsychParser extends RubyObject { // If we can't get it from the IO or it doesn't have a charset, fall back on UTF-8 charset = UTF8Encoding.INSTANCE.getCharset(); } - return new StreamReader(new InputStreamReader(new IOInputStream(yaml), charset)); + CharsetDecoder decoder = charset.newDecoder(); + decoder.onMalformedInput(CodingErrorAction.REPORT); + decoder.onMalformedInput(CodingErrorAction.REPORT); + + return new StreamReader(new InputStreamReader(new IOInputStream(yaml), decoder)); } else { throw runtime.newTypeError(yaml, runtime.getIO()); } @@ -248,6 +258,16 @@ public class PsychParser extends RubyObject { parser = null; raiseParserException(context, yaml, re, path); + } catch (YAMLException ye) { + Throwable cause = ye.getCause(); + + if (cause instanceof MalformedInputException) { + // failure due to improperly encoded input + raiseParserException(context, yaml, (MalformedInputException) cause, path); + } + + throw ye; + } catch (Throwable t) { Helpers.throwException(t); return this; @@ -359,6 +379,31 @@ public class PsychParser extends RubyObject { RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK); } + private static void raiseParserException(ThreadContext context, IRubyObject yaml, MalformedInputException mie, IRubyObject rbPath) { + Ruby runtime; + Mark mark; + RubyClass se; + IRubyObject exception; + + runtime = context.runtime; + se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError"); + + mie.getInputLength(); + + exception = se.newInstance(context, + arrayOf( + rbPath, + runtime.newFixnum(-1), + runtime.newFixnum(-1), + runtime.newFixnum(mie.getInputLength()), + runtime.getNil(), + runtime.getNil() + ), + Block.NULL_BLOCK); + + RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK); + } + private static int translateStyle(DumperOptions.ScalarStyle style) { if (style == null) return 0; // any -- cgit v1.2.1 From ca1c154bd8d610e2dc5aa2f0443d0fd9b3e29a5f Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 25 Feb 2021 17:49:36 -0600 Subject: Clean up type checks and trancodes --- ext/java/org/jruby/ext/psych/PsychEmitter.java | 88 +++++++++++++++----------- 1 file changed, 51 insertions(+), 37 deletions(-) (limited to 'ext') diff --git a/ext/java/org/jruby/ext/psych/PsychEmitter.java b/ext/java/org/jruby/ext/psych/PsychEmitter.java index ec71b93..1026f00 100644 --- a/ext/java/org/jruby/ext/psych/PsychEmitter.java +++ b/ext/java/org/jruby/ext/psych/PsychEmitter.java @@ -114,9 +114,7 @@ public class PsychEmitter extends RubyObject { @JRubyMethod public IRubyObject start_stream(ThreadContext context, IRubyObject encoding) { - if (!(encoding instanceof RubyFixnum)) { - throw context.runtime.newTypeError(encoding, context.runtime.getFixnum()); - } + TypeConverter.checkType(context, encoding, context.runtime.getFixnum()); initEmitter(context, encoding); @@ -140,6 +138,8 @@ public class PsychEmitter extends RubyObject { boolean implicitBool = implicit.isTrue(); Map tagsMap = null; + TypeConverter.checkType(context, _version, context.runtime.getArray()); + RubyArray versionAry = _version.convertToArray(); if (versionAry.size() == 2) { int versionInt0 = (int)versionAry.eltInternal(0).convertToInteger().getLongValue(); @@ -157,19 +157,23 @@ public class PsychEmitter extends RubyObject { } } - RubyArray tagsAry = tags.convertToArray(); - if (tagsAry.size() > 0) { - tagsMap = new HashMap(tagsAry.size()); - for (int i = 0; i < tagsAry.size(); i++) { - RubyArray tagsTuple = tagsAry.eltInternal(i).convertToArray(); - if (tagsTuple.size() != 2) { - throw context.runtime.newRuntimeError("tags tuple must be of length 2"); + if (!tags.isNil()) { + TypeConverter.checkType(context, tags, context.runtime.getArray()); + + RubyArray tagsAry = tags.convertToArray(); + if (tagsAry.size() > 0) { + tagsMap = new HashMap<>(tagsAry.size()); + for (int i = 0; i < tagsAry.size(); i++) { + RubyArray tagsTuple = tagsAry.eltInternal(i).convertToArray(); + if (tagsTuple.size() != 2) { + throw context.runtime.newRuntimeError("tags tuple must be of length 2"); + } + IRubyObject key = tagsTuple.eltInternal(0); + IRubyObject value = tagsTuple.eltInternal(1); + tagsMap.put( + key.asJavaString(), + value.asJavaString()); } - IRubyObject key = tagsTuple.eltInternal(0); - IRubyObject value = tagsTuple.eltInternal(1); - tagsMap.put( - key.asJavaString(), - value.asJavaString()); } } @@ -199,23 +203,11 @@ public class PsychEmitter extends RubyObject { TypeConverter.checkType(context, value, stringClass); RubyString valueStr = (RubyString) value; - Encoding encoding = UTF8Encoding.INSTANCE; - valueStr = EncodingUtils.strConvEnc(context, valueStr, valueStr.getEncoding(), encoding); + valueStr = EncodingUtils.strConvEnc(context, valueStr, valueStr.getEncoding(), UTF8Encoding.INSTANCE); - RubyString anchorStr = null; - if (!anchor.isNil()) { - TypeConverter.checkType(context, anchor, stringClass); - anchorStr = (RubyString) anchor; - anchorStr = EncodingUtils.strConvEnc(context, anchorStr, anchorStr.getEncoding(), encoding); - } - - RubyString tagStr = null; - if (!tag.isNil()) { - TypeConverter.checkType(context, tag, stringClass); - tagStr = (RubyString) tag; - tagStr = EncodingUtils.strConvEnc(context, tagStr, tagStr.getEncoding(), encoding); - } + RubyString anchorStr = exportToUTF8(context, anchor, stringClass); + RubyString tagStr = exportToUTF8(context, tag, stringClass); ScalarEvent event = new ScalarEvent( anchorStr == null ? null : anchorStr.asJavaString(), @@ -238,11 +230,14 @@ public class PsychEmitter extends RubyObject { IRubyObject implicit = args[2]; IRubyObject style = args[3]; - final int SEQUENCE_BLOCK = 1; // see psych/nodes/sequence.rb + RubyClass stringClass = context.runtime.getString(); + + RubyString anchorStr = exportToUTF8(context, anchor, stringClass); + RubyString tagStr = exportToUTF8(context, tag, stringClass); SequenceStartEvent event = new SequenceStartEvent( - anchor.isNil() ? null : anchor.asJavaString(), - tag.isNil() ? null : tag.asJavaString(), + anchorStr == null ? null : anchorStr.asJavaString(), + tagStr == null ? null : tagStr.asJavaString(), implicit.isTrue(), NULL_MARK, NULL_MARK, @@ -265,16 +260,21 @@ public class PsychEmitter extends RubyObject { IRubyObject implicit = args[2]; IRubyObject style = args[3]; - final int MAPPING_BLOCK = 1; // see psych/nodes/mapping.rb + RubyClass stringClass = context.runtime.getString(); + + RubyString anchorStr = exportToUTF8(context, anchor, stringClass); + RubyString tagStr = exportToUTF8(context, tag, stringClass); MappingStartEvent event = new MappingStartEvent( - anchor.isNil() ? null : anchor.asJavaString(), - tag.isNil() ? null : tag.asJavaString(), + anchorStr == null ? null : anchorStr.asJavaString(), + tagStr == null ? null : tagStr.asJavaString(), implicit.isTrue(), NULL_MARK, NULL_MARK, FLOW_STYLES[style.convertToInteger().getIntValue()]); + emit(context, event); + return this; } @@ -287,7 +287,11 @@ public class PsychEmitter extends RubyObject { @JRubyMethod public IRubyObject alias(ThreadContext context, IRubyObject anchor) { - AliasEvent event = new AliasEvent(anchor.asJavaString(), NULL_MARK, NULL_MARK); + RubyClass stringClass = context.runtime.getString(); + + RubyString anchorStr = exportToUTF8(context, anchor, stringClass); + + AliasEvent event = new AliasEvent(anchorStr.asJavaString(), NULL_MARK, NULL_MARK); emit(context, event); return this; } @@ -356,6 +360,16 @@ public class PsychEmitter extends RubyObject { emitter = new Emitter(writer, options); } + private RubyString exportToUTF8(ThreadContext context, IRubyObject tag, RubyClass stringClass) { + RubyString tagStr = null; + if (!tag.isNil()) { + TypeConverter.checkType(context, tag, stringClass); + tagStr = (RubyString) tag; + tagStr = EncodingUtils.strConvEnc(context, tagStr, tagStr.getEncoding(), UTF8Encoding.INSTANCE); + } + return tagStr; + } + Emitter emitter; Writer writer; DumperOptions options = new DumperOptions(); -- cgit v1.2.1 From bce2752499cce7a4697442e50ebc20f2f78e4a3e Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 25 Feb 2021 17:49:59 -0600 Subject: Minor optimization --- ext/java/org/jruby/ext/psych/PsychEmitter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ext') diff --git a/ext/java/org/jruby/ext/psych/PsychEmitter.java b/ext/java/org/jruby/ext/psych/PsychEmitter.java index 1026f00..be6e388 100644 --- a/ext/java/org/jruby/ext/psych/PsychEmitter.java +++ b/ext/java/org/jruby/ext/psych/PsychEmitter.java @@ -38,6 +38,7 @@ import org.jcodings.Encoding; import org.jcodings.specific.UTF8Encoding; import org.jruby.Ruby; import org.jruby.RubyArray; +import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; @@ -306,7 +307,7 @@ public class PsychEmitter extends RubyObject { @JRubyMethod public IRubyObject canonical(ThreadContext context) { // TODO: unclear if this affects a running emitter - return context.runtime.newBoolean(options.isCanonical()); + return RubyBoolean.newBoolean(context, options.isCanonical()); } @JRubyMethod(name = "indentation=") -- cgit v1.2.1 From d0165b6aa96f9b207cf11282305e856922678bf1 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 25 Feb 2021 17:59:29 -0600 Subject: Minor optimization: defer runtime access --- ext/java/org/jruby/ext/psych/PsychParser.java | 34 ++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'ext') diff --git a/ext/java/org/jruby/ext/psych/PsychParser.java b/ext/java/org/jruby/ext/psych/PsychParser.java index 3bc4a44..8539110 100644 --- a/ext/java/org/jruby/ext/psych/PsychParser.java +++ b/ext/java/org/jruby/ext/psych/PsychParser.java @@ -115,13 +115,15 @@ public class PsychParser extends RubyObject { return parse(context, yaml, runtime.getNil()); } - private IRubyObject stringOrNilFor(Ruby runtime, String value, boolean tainted) { - if (value == null) return runtime.getNil(); // No need to taint nil + private IRubyObject stringOrNilFor(ThreadContext context, String value, boolean tainted) { + if (value == null) return context.nil; - return stringFor(runtime, value, tainted); + return stringFor(context, value, tainted); } - private RubyString stringFor(Ruby runtime, String value, boolean tainted) { + private RubyString stringFor(ThreadContext context, String value, boolean tainted) { + Ruby runtime = context.runtime; + Encoding encoding = runtime.getDefaultInternalEncoding(); if (encoding == null) { encoding = UTF8Encoding.INSTANCE; @@ -141,8 +143,6 @@ public class PsychParser extends RubyObject { } private StreamReader readerFor(ThreadContext context, IRubyObject yaml) { - Ruby runtime = context.runtime; - if (yaml instanceof RubyString) { ByteList byteList = ((RubyString)yaml).getByteList(); Encoding enc = byteList.getEncoding(); @@ -186,6 +186,8 @@ public class PsychParser extends RubyObject { return new StreamReader(new InputStreamReader(new IOInputStream(yaml), decoder)); } else { + Ruby runtime = context.runtime; + throw runtime.newTypeError(yaml, runtime.getIO()); } } @@ -223,7 +225,7 @@ public class PsychParser extends RubyObject { invoke(context, handler, "end_document", notExplicit); } else if (event.is(ID.Alias)) { - IRubyObject alias = stringOrNilFor(runtime, ((AliasEvent)event).getAnchor(), tainted); + IRubyObject alias = stringOrNilFor(context, ((AliasEvent)event).getAnchor(), tainted); invoke(context, handler, "alias", alias); } else if (event.is(ID.Scalar)) { @@ -287,8 +289,8 @@ public class PsychParser extends RubyObject { RubyArray tags = RubyArray.newArray(runtime); if (tagsMap != null && tagsMap.size() > 0) { for (Map.Entry tag : tagsMap.entrySet()) { - IRubyObject key = stringFor(runtime, tag.getKey(), tainted); - IRubyObject value = stringFor(runtime, tag.getValue(), tainted); + IRubyObject key = stringFor(context, tag.getKey(), tainted); + IRubyObject value = stringFor(context, tag.getValue(), tainted); tags.append(RubyArray.newArray(runtime, key, value)); } @@ -300,8 +302,8 @@ public class PsychParser extends RubyObject { private void handleMappingStart(ThreadContext context, MappingStartEvent mse, boolean tainted, IRubyObject handler) { Ruby runtime = context.runtime; - IRubyObject anchor = stringOrNilFor(runtime, mse.getAnchor(), tainted); - IRubyObject tag = stringOrNilFor(runtime, mse.getTag(), tainted); + IRubyObject anchor = stringOrNilFor(context, mse.getAnchor(), tainted); + IRubyObject tag = stringOrNilFor(context, mse.getTag(), tainted); IRubyObject implicit = runtime.newBoolean(mse.getImplicit()); IRubyObject style = runtime.newFixnum(translateFlowStyle(mse.getFlowStyle())); @@ -311,12 +313,12 @@ public class PsychParser extends RubyObject { private void handleScalar(ThreadContext context, ScalarEvent se, boolean tainted, IRubyObject handler) { Ruby runtime = context.runtime; - IRubyObject anchor = stringOrNilFor(runtime, se.getAnchor(), tainted); - IRubyObject tag = stringOrNilFor(runtime, se.getTag(), tainted); + IRubyObject anchor = stringOrNilFor(context, se.getAnchor(), tainted); + IRubyObject tag = stringOrNilFor(context, se.getTag(), tainted); IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInPlainScalar()); IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar()); IRubyObject style = runtime.newFixnum(translateStyle(se.getScalarStyle())); - IRubyObject val = stringFor(runtime, se.getValue(), tainted); + IRubyObject val = stringFor(context, se.getValue(), tainted); invoke(context, handler, "scalar", val, anchor, tag, plain_implicit, quoted_implicit, style); @@ -324,8 +326,8 @@ public class PsychParser extends RubyObject { private void handleSequenceStart(ThreadContext context, SequenceStartEvent sse, boolean tainted, IRubyObject handler) { Ruby runtime = context.runtime; - IRubyObject anchor = stringOrNilFor(runtime, sse.getAnchor(), tainted); - IRubyObject tag = stringOrNilFor(runtime, sse.getTag(), tainted); + IRubyObject anchor = stringOrNilFor(context, sse.getAnchor(), tainted); + IRubyObject tag = stringOrNilFor(context, sse.getTag(), tainted); IRubyObject implicit = runtime.newBoolean(sse.getImplicit()); IRubyObject style = runtime.newFixnum(translateFlowStyle(sse.getFlowStyle())); -- cgit v1.2.1