diff --git a/core/src/main/java/org/jruby/parser/RubyParserBase.java b/core/src/main/java/org/jruby/parser/RubyParserBase.java index 585b1da0965..eef9a529f87 100644 --- a/core/src/main/java/org/jruby/parser/RubyParserBase.java +++ b/core/src/main/java/org/jruby/parser/RubyParserBase.java @@ -585,7 +585,7 @@ public Node attrset(Node receiver, ByteList name) { } public Node attrset(Node receiver, ByteList callType, ByteList name) { - return new_attrassign(receiver.getLine(), receiver, name.append('='), null, isLazy(callType)); + return new_attrassign(receiver.getLine(), receiver, name.copyAndAppend('='), null, isLazy(callType)); } public void backrefAssignError(Node node) { diff --git a/core/src/main/java/org/jruby/util/ByteList.java b/core/src/main/java/org/jruby/util/ByteList.java index 1765e26c60a..9038e921c3d 100644 --- a/core/src/main/java/org/jruby/util/ByteList.java +++ b/core/src/main/java/org/jruby/util/ByteList.java @@ -38,6 +38,7 @@ import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -459,6 +460,29 @@ public ByteList append(byte b) { return this; } + /** + * Create a new ByteList one byte longer with that element populated by the given byte. + *

+ * Subsequent appends will make new byte[] copies, so this should only be used to create a single new ByteList of + * size == realSize + 1. + * + * @param bite the byte to append when copying to a new ByteList + * @return a new ByteList with the given byte appended + */ + public ByteList copyAndAppend(int bite) { + byte[] bytes = this.bytes; + int realSize = this.realSize; + int begin = this.begin; + + byte[] newBytes = Arrays.copyOfRange(bytes, begin, begin + realSize + 1); + + newBytes[realSize] = (byte) bite; + + ByteList bl = new ByteList(newBytes, 0, realSize + 1, encoding, false); + + return bl; + } + /** * Append a single byte to the ByteList by truncating the given int *