Skip to content

Instantly share code, notes, and snippets.

@enebo

enebo/a.diff Secret

Created November 7, 2019 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enebo/76886a06f38b18d54c24ed93d273ade7 to your computer and use it in GitHub Desktop.
Save enebo/76886a06f38b18d54c24ed93d273ade7 to your computer and use it in GitHub Desktop.
diff --git a/core/src/main/java/org/jruby/RubyString.java b/core/src/main/java/org/jruby/RubyString.java
index a1a06fefba..deb9ccd27d 100644
--- a/core/src/main/java/org/jruby/RubyString.java
+++ b/core/src/main/java/org/jruby/RubyString.java
@@ -3208,7 +3208,7 @@ public class RubyString extends RubyObject implements CharSequence, EncodingCapa
final int patternLen = pattern.size();
final Encoding patternEnc = this.checkEncoding(pattern);
- int beg = StringSupport.index(this, pattern, 0, patternEnc);
+ int beg = StringSupport.index(getByteList(), pattern.getByteList(), 0, patternEnc);
int begz;
if (beg < 0) {
if (useBackref) context.setBackRef(context.nil);
@@ -3258,7 +3258,7 @@ public class RubyString extends RubyObject implements CharSequence, EncodingCapa
}
cp = spBeg + offset;
if (offset > spLen) break;
- beg = StringSupport.index(this, pattern, offset, patternEnc);
+ beg = StringSupport.index(getByteList(), pattern.getByteList(), offset, patternEnc);
} while (beg >= 0);
if (spLen > offset) dest.cat(spBytes, cp, spLen - offset, str_enc);
diff --git a/core/src/main/java/org/jruby/util/StringSupport.java b/core/src/main/java/org/jruby/util/StringSupport.java
index 5790ac76bb..6ee1c5d759 100644
--- a/core/src/main/java/org/jruby/util/StringSupport.java
+++ b/core/src/main/java/org/jruby/util/StringSupport.java
@@ -1616,6 +1616,38 @@ public final class StringSupport {
return string.getCodeRange() == CR_7BIT || encoding.maxLength() == 1;
}
+ /**
+ *
+ * @param source string to find index within
+ * @param other string to match in source
+ * @param offset in bytes to start looking
+ * @param enc encoding to use to walk the source string.
+ * @return
+ */
+ public static int index(ByteList source, ByteList other, int offset, Encoding enc) {
+ int sourceLen = source.realSize();
+ int sourceBegin = source.begin();
+ int otherLen = other.realSize();
+
+ if (otherLen == 0) return offset;
+ if (sourceLen - offset < otherLen) return -1;
+
+ byte[] sourceBytes = source.getUnsafeBytes();
+ int p = sourceBegin + offset;
+ int end = p + sourceLen;
+
+ while (true) {
+ int pos = source.indexOf(other, p - sourceBegin);
+ if (pos < 0) return pos;
+ pos -= (p - sourceBegin);
+ int t = enc.rightAdjustCharHead(sourceBytes, p, p + pos, end);
+ if (t == p + pos) return pos + offset;
+ if ((sourceLen -= t - p) <= 0) return -1;
+ offset += t - p;
+ p = t;
+ }
+ }
+
public static int index(CodeRangeable sourceString, CodeRangeable otherString, int offset, Encoding enc) {
if (otherString.scanForCodeRange() == CR_BROKEN) return -1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment