Skip to content

Commit

Permalink
Merge pull request #5037 from jruby/fix-2036-9.1
Browse files Browse the repository at this point in the history
align C ported memsearch code - need to handle array[length] properly
  • Loading branch information
kares committed Feb 14, 2018
2 parents ba92c73 + bc39a0a commit 23f53d3
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
Expand Up @@ -2728,7 +2728,6 @@ private IRubyObject indexCommon19(Ruby runtime, ThreadContext context, IRubyObje

// MRI: rb_strseq_index
private int strseqIndex(final RubyString sub, int offset, boolean inBytes) {
byte[] sBytes = value.unsafeBytes();
int s, sptr, e;
int pos, len, slen;
boolean single_byte = singleByteOptimizable();
Expand All @@ -2745,6 +2744,7 @@ private int strseqIndex(final RubyString sub, int offset, boolean inBytes) {
}
if (len - offset < slen) return -1;

byte[] sBytes = value.unsafeBytes();
s = value.begin();
e = s + value.realSize();
if (offset != 0) {
Expand Down Expand Up @@ -3811,7 +3811,7 @@ public IRubyObject scan19(ThreadContext context, IRubyObject pat, Block block) {
mustnotBroken(context);
if (!block.isGiven()) {
RubyArray ary = null;
while (!(result = scanOnce(context, str, pat, startp)).isNil()) {
while ((result = scanOnce(context, str, pat, startp)) != context.nil) {
last = prev;
prev = startp[0];
if (ary == null) ary = context.runtime.newArray(4);
Expand All @@ -3824,7 +3824,7 @@ public IRubyObject scan19(ThreadContext context, IRubyObject pat, Block block) {
final byte[] pBytes = value.unsafeBytes();
final int len = value.realSize();

while (!(result = scanOnce(context, str, pat, startp)).isNil()) {
while ((result = scanOnce(context, str, pat, startp)) != context.nil) {
last = prev;
prev = startp[0];
block.yieldSpecific(context, result);
Expand Down
14 changes: 10 additions & 4 deletions core/src/main/java/org/jruby/util/StringSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -2297,9 +2297,15 @@ private static int rb_memsearch_qs(byte[] xsBytes, int xs, int m, byte[] ysBytes
return -1;
}

private static int rb_memsearch_qs_utf8_hash(byte[] xBytes, int x) {
int mix = 8353;
int h = xBytes[x] & 0xFF;
private static int rb_memsearch_qs_utf8_hash(byte[] xBytes, final int x) {
final int mix = 8353;
int h;
if (x != xBytes.length) {
h = xBytes[x] & 0xFF;
}
else {
h = '\0'; // (C) ary end - due y+m at rb_memsearch_qs_utf8
}
if (h < 0xC0) {
return h + 256;
}
Expand Down Expand Up @@ -2337,7 +2343,7 @@ private static int rb_memsearch_qs_utf8(byte[] xsBytes, int xs, int m, byte[] ys
for (; x < xe; ++x) {
qstable[rb_memsearch_qs_utf8_hash(xsBytes, x)] = xe - x;
}
/* Searching */
/* Searching */ // due y+m <= ... (y+m) might == ary.length
for (; y + m <= ys + n; y += qstable[rb_memsearch_qs_utf8_hash(ysBytes, y+m)]) {
if (xsBytes[xs] == ysBytes[y] && ByteList.memcmp(xsBytes, xs, ysBytes, y, m) == 0)
return y - ys;
Expand Down
13 changes: 13 additions & 0 deletions test/jruby/test_string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,17 @@ def try(obj, *a, &b) # ~ AS 4.2
end
end

public

def test_scan_error
string = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
assert_equal [], 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'.scan('d....r........')

('a'..'z').to_a.each do |c1|
('a'..'z').to_a.each do |c2|
string.downcase.scan("#{c1}....#{c2}........") # does not blow with ArrayIndexOutOfBoundsException
end
end
end

end

0 comments on commit 23f53d3

Please sign in to comment.