Skip to content

Commit

Permalink
Fix parser appending directly to an identifier
Browse files Browse the repository at this point in the history
This appears to be the only place in the parser logic where a
possibly-shared identifier ByteList is directly modified. This
breaks the previous commit's use of shared single-byte ByteLists.
  • Loading branch information
headius committed Aug 22, 2024
1 parent 7a169a2 commit b2e2172
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/parser/RubyParserBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
24 changes: 24 additions & 0 deletions core/src/main/java/org/jruby/util/ByteList.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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.
* <p>
* 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
*
Expand Down

0 comments on commit b2e2172

Please sign in to comment.