tags 1042129 + patch
thanks

Upstream handled this when they upgraded Joni dependency to 2.2 on
JRuby 9.4 series.

https://github.com/jruby/jruby/commit/3c94d31f1e198f294e9bfcb96b4188c315252b6b

https://github.com/jruby/jruby/commit/783d14bcb140477bb2577310a90742d594a48896

See attached a fix for this issue.
diff -Nru jruby-9.3.9.0+ds/debian/changelog jruby-9.3.9.0+ds/debian/changelog
--- jruby-9.3.9.0+ds/debian/changelog   2023-01-16 21:08:51.000000000 +0000
+++ jruby-9.3.9.0+ds/debian/changelog   2023-11-24 11:48:05.000000000 +0000
@@ -1,3 +1,11 @@
+jruby (9.3.9.0+ds-9~miguel1) UNRELEASED; urgency=medium
+
+  * Fix FTBFS: adapt and backport changes from 9.4 releases
+    to accomodate for changes in regexp library Joni 2.2.
+    (Closes: #1042129)
+
+ -- Miguel Landaeta <nomad...@debian.org>  Fri, 24 Nov 2023 11:48:05 +0000
+
 jruby (9.3.9.0+ds-8) unstable; urgency=medium
 
   * d/tests: flag jirb test as flaky
diff -Nru 
jruby-9.3.9.0+ds/debian/patches/0012-Use-Region-accessors-in-prep-for-privatizing-fields.patch
 
jruby-9.3.9.0+ds/debian/patches/0012-Use-Region-accessors-in-prep-for-privatizing-fields.patch
--- 
jruby-9.3.9.0+ds/debian/patches/0012-Use-Region-accessors-in-prep-for-privatizing-fields.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
jruby-9.3.9.0+ds/debian/patches/0012-Use-Region-accessors-in-prep-for-privatizing-fields.patch
      2023-11-24 11:48:05.000000000 +0000
@@ -0,0 +1,390 @@
+Subject: Use Region accessors in prep for privatizing fields
+Forwarded: 
https://github.com/jruby/jruby/commit/3c94d31f1e198f294e9bfcb96b4188c315252b6b
+--
+diff --git a/core/src/main/java/org/jruby/RubyMatchData.java 
b/core/src/main/java/org/jruby/RubyMatchData.java
+index 48fa92b..87e7c9d 100644
+--- a/core/src/main/java/org/jruby/RubyMatchData.java
++++ b/core/src/main/java/org/jruby/RubyMatchData.java
+@@ -175,11 +175,11 @@ public class RubyMatchData extends RubyObject {
+     private void updateCharOffsetOnlyOneReg(ByteList value, Encoding 
encoding) {
+         if (charOffsetUpdated) return;
+ 
+-        if (charOffsets == null || charOffsets.numRegs < 1) charOffsets = new 
Region(1);
++        if (charOffsets == null || charOffsets.getNumRegs() < 1) charOffsets 
= new Region(1);
+ 
+         if (encoding.maxLength() == 1) {
+-            charOffsets.beg[0] = begin;
+-            charOffsets.end[0] = end;
++            charOffsets.setBeg(0, begin);
++            charOffsets.setEnd(0, end);
+             charOffsetUpdated = true;
+             return;
+         }
+@@ -195,14 +195,14 @@ public class RubyMatchData extends RubyObject {
+         updatePairs(value, encoding, pairs);
+ 
+         if (begin < 0) {
+-            charOffsets.beg[0] = charOffsets.end[0] = -1;
++            charOffsets.setBeg(0, charOffsets.setEnd(0, -1));
+             return;
+         }
+         Pair key = new Pair();
+         key.bytePos = begin;
+-        charOffsets.beg[0] = pairs[Arrays.binarySearch(pairs, key)].charPos;
++        charOffsets.setBeg(0, pairs[Arrays.binarySearch(pairs, key)].charPos);
+         key.bytePos = end;
+-        charOffsets.end[0] = pairs[Arrays.binarySearch(pairs, key)].charPos;
++        charOffsets.setEnd(0, pairs[Arrays.binarySearch(pairs, key)].charPos);
+ 
+         charOffsetUpdated = true;
+     }
+@@ -211,14 +211,14 @@ public class RubyMatchData extends RubyObject {
+         if (charOffsetUpdated) return;
+ 
+         final Region regs = this.regs;
+-        int numRegs = regs.numRegs;
++        int numRegs = regs.getNumRegs();
+ 
+-        if (charOffsets == null || charOffsets.numRegs < numRegs) charOffsets 
= new Region(numRegs);
++        if (charOffsets == null || charOffsets.getNumRegs() < numRegs) 
charOffsets = new Region(numRegs);
+ 
+         if (encoding.maxLength() == 1) {
+             for (int i = 0; i < numRegs; i++) {
+-                charOffsets.beg[i] = regs.beg[i];
+-                charOffsets.end[i] = regs.end[i];
++                charOffsets.setBeg(i, regs.getBeg(i));
++                charOffsets.setEnd(i, regs.getEnd(i));
+             }
+             charOffsetUpdated = true;
+             return;
+@@ -229,23 +229,23 @@ public class RubyMatchData extends RubyObject {
+ 
+         int numPos = 0;
+         for (int i = 0; i < numRegs; i++) {
+-            if (regs.beg[i] < 0) continue;
+-            pairs[numPos++].bytePos = regs.beg[i];
+-            pairs[numPos++].bytePos = regs.end[i];
++            if (regs.getBeg(i) < 0) continue;
++            pairs[numPos++].bytePos = regs.getBeg(i);
++            pairs[numPos++].bytePos = regs.getEnd(i);
+         }
+ 
+         updatePairs(value, encoding, pairs);
+ 
+         Pair key = new Pair();
+-        for (int i = 0; i < regs.numRegs; i++) {
+-            if (regs.beg[i] < 0) {
+-                charOffsets.beg[i] = charOffsets.end[i] = -1;
++        for (int i = 0; i < regs.getNumRegs(); i++) {
++            if (regs.getBeg(i) < 0) {
++                charOffsets.setBeg(i, charOffsets.setEnd(i, -1));
+                 continue;
+             }
+-            key.bytePos = regs.beg[i];
+-            charOffsets.beg[i] = pairs[Arrays.binarySearch(pairs, 
key)].charPos;
+-            key.bytePos = regs.end[i];
+-            charOffsets.end[i] = pairs[Arrays.binarySearch(pairs, 
key)].charPos;
++            key.bytePos = regs.getBeg(i);
++            charOffsets.setBeg(i, pairs[Arrays.binarySearch(pairs, 
key)].charPos);
++            key.bytePos = regs.getEnd(i);
++            charOffsets.setEnd(i, pairs[Arrays.binarySearch(pairs, 
key)].charPos);
+         }
+ 
+         charOffsetUpdated = true;
+@@ -314,13 +314,13 @@ public class RubyMatchData extends RubyObject {
+                 return runtime.newArray( ss.infectBy(this) );
+             }
+         } else {
+-            RubyArray arr = RubyArray.newBlankArray(runtime, regs.numRegs - 
start);
++            RubyArray arr = RubyArray.newBlankArray(runtime, 
regs.getNumRegs() - start);
+             int index = 0;
+-            for (int i=start; i < regs.numRegs; i++) {
+-                if (regs.beg[i] == -1) {
++            for (int i=start; i < regs.getNumRegs(); i++) {
++                if (regs.getBeg(i) == -1) {
+                     arr.storeInternal(index++, nil);
+                 } else {
+-                    RubyString ss = makeShared(runtime, str, regs.beg[i], 
regs.end[i] - regs.beg[i]);
++                    RubyString ss = makeShared(runtime, str, regs.getBeg(i), 
regs.getEnd(i) - regs.getBeg(i));
+                     arr.storeInternal(index++, ss.infectBy(this));
+                 }
+             }
+@@ -375,7 +375,7 @@ public class RubyMatchData extends RubyObject {
+         result.cat((byte)'#').cat((byte)'<');
+         result.append(getMetaClass().getRealClass().to_s());
+ 
+-        NameEntry[] names = new NameEntry[regs == null ? 1 : regs.numRegs];
++        NameEntry[] names = new NameEntry[regs == null ? 1 : 
regs.getNumRegs()];
+ 
+         final Regex pattern = getPattern();
+         for (Iterator<NameEntry> i = pattern.namedBackrefIterator(); 
i.hasNext();) {
+@@ -520,7 +520,7 @@ public class RubyMatchData extends RubyObject {
+     private IRubyObject matchArySubseq(ThreadContext context, int beg, int 
len, RubyArray result) {
+         assert result != null;
+ 
+-        int olen = regs.numRegs;
++        int olen = regs.getNumRegs();
+         int wantedEnd = beg + len;
+         int j, end = olen < wantedEnd ? olen : wantedEnd;
+ 
+@@ -542,7 +542,7 @@ public class RubyMatchData extends RubyObject {
+     // MRI: match_ary_aref
+     private IRubyObject matchAryAref(ThreadContext context, IRubyObject 
index, RubyArray result) {
+         int[] begLen = new int[2];
+-        int numRegs = regs.numRegs;
++        int numRegs = regs.getNumRegs();
+ 
+         /* check if idx is Range */
+         IRubyObject isRange = RubyRange.rangeBeginLength(context, index, 
numRegs, begLen, 1);
+@@ -612,7 +612,7 @@ public class RubyMatchData extends RubyObject {
+     public IRubyObject size(ThreadContext context) {
+         check();
+         Ruby runtime = context.runtime;
+-        return regs == null ? RubyFixnum.one(runtime) : 
RubyFixnum.newFixnum(runtime, regs.numRegs);
++        return regs == null ? RubyFixnum.one(runtime) : 
RubyFixnum.newFixnum(runtime, regs.getNumRegs());
+     }
+ 
+     /**
+@@ -624,17 +624,17 @@ public class RubyMatchData extends RubyObject {
+         final Ruby runtime = context.runtime;
+         final int i = backrefNumber(runtime, index);
+ 
+-        if (i < 0 || (regs == null ? 1 : regs.numRegs) <= i) {
++        if (i < 0 || (regs == null ? 1 : regs.getNumRegs()) <= i) {
+             throw runtime.newIndexError("index " + i + " out of matches");
+         }
+ 
+-        int b = regs == null ? begin : regs.beg[i];
++        int b = regs == null ? begin : regs.getBeg(i);
+ 
+         if (b < 0) return context.nil;
+ 
+         updateCharOffset();
+ 
+-        return RubyFixnum.newFixnum(runtime, charOffsets.beg[i]);
++        return RubyFixnum.newFixnum(runtime, charOffsets.getBeg(i));
+     }
+ 
+     /** match_end
+@@ -647,17 +647,17 @@ public class RubyMatchData extends RubyObject {
+         final Ruby runtime = context.runtime;
+         final int i = backrefNumber(runtime, index);
+ 
+-        if (i < 0 || (regs == null ? 1 : regs.numRegs) <= i) {
++        if (i < 0 || (regs == null ? 1 : regs.getNumRegs()) <= i) {
+             throw runtime.newIndexError("index " + i + " out of matches");
+         }
+ 
+-        int e = regs == null ? end : regs.end[i];
++        int e = regs == null ? end : regs.getEnd(i);
+ 
+         if (e < 0) return context.nil;
+ 
+         if ( ! str.singleByteOptimizable() ) {
+             updateCharOffset();
+-            e = charOffsets.end[i];
++            e = charOffsets.getEnd(i);
+         }
+ 
+         return RubyFixnum.newFixnum(runtime, e);
+@@ -677,7 +677,7 @@ public class RubyMatchData extends RubyObject {
+         final Ruby runtime = context.runtime;
+         final int i = backrefNumber(runtime, index);
+ 
+-        if (i < 0 || (regs == null ? 1 : regs.numRegs) <= i) {
++        if (i < 0 || (regs == null ? 1 : regs.getNumRegs()) <= i) {
+             throw runtime.newIndexError("index " + i + " out of matches");
+         }
+ 
+@@ -686,16 +686,16 @@ public class RubyMatchData extends RubyObject {
+             b = begin;
+             e = end;
+         } else {
+-            b = regs.beg[i];
+-            e = regs.end[i];
++            b = regs.getBeg(i);
++            e = regs.getEnd(i);
+         }
+ 
+         if (b < 0) return runtime.newArray(context.nil, context.nil);
+ 
+         if ( ! str.singleByteOptimizable() ) {
+             updateCharOffset();
+-            b = charOffsets.beg[i];
+-            e = charOffsets.end[i];
++            b = charOffsets.getBeg(i);
++            e = charOffsets.getEnd(i);
+         }
+ 
+         return runtime.newArray(RubyFixnum.newFixnum(runtime, b), 
RubyFixnum.newFixnum(runtime, e));
+@@ -833,8 +833,8 @@ public class RubyMatchData extends RubyObject {
+             if (i > 1) return -1;
+             return begin;
+         }
+-        if (i > regs.numRegs) return -1;
+-        return regs.beg[i];
++        if (i > regs.getNumRegs()) return -1;
++        return regs.getBeg(i);
+     }
+ 
+     /**
+@@ -848,8 +848,8 @@ public class RubyMatchData extends RubyObject {
+             if (i > 1) return -1;
+             return end;
+         }
+-        if (i > regs.numRegs) return -1;
+-        return regs.end[i];
++        if (i > regs.getNumRegs()) return -1;
++        return regs.getEnd(i);
+     }
+ 
+     /**
+@@ -858,7 +858,7 @@ public class RubyMatchData extends RubyObject {
+      * @return the number of regions in this match
+      */
+     public int numRegs() {
+-        return regs == null ? 1 : regs.numRegs;
++        return regs == null ? 1 : regs.getNumRegs();
+     }
+ 
+     @Deprecated
+diff --git a/core/src/main/java/org/jruby/RubyRegexp.java 
b/core/src/main/java/org/jruby/RubyRegexp.java
+index 66852ee..229895f 100755
+--- a/core/src/main/java/org/jruby/RubyRegexp.java
++++ b/core/src/main/java/org/jruby/RubyRegexp.java
+@@ -1588,11 +1588,11 @@ public class RubyRegexp extends RubyObject implements 
ReOptions, EncodingCapable
+             start = match.begin;
+             end = match.end;
+         } else {
+-            if (nth >= match.regs.numRegs || (nth < 0 && 
(nth+=match.regs.numRegs) <= 0)) {
++            if (nth >= match.regs.getNumRegs() || (nth < 0 && 
(nth+=match.regs.getNumRegs()) <= 0)) {
+                 return match.getRuntime().getNil();
+             }
+-            start = match.regs.beg[nth];
+-            end = match.regs.end[nth];
++            start = match.regs.getBeg(nth);
++            end = match.regs.getEnd(nth);
+         }
+ 
+         if (start == -1) return match.getRuntime().getNil();
+@@ -1643,10 +1643,10 @@ public class RubyRegexp extends RubyObject implements 
ReOptions, EncodingCapable
+         RubyMatchData m = (RubyMatchData) match;
+         m.check();
+ 
+-        if (m.regs == null || m.regs.beg[0] == -1) return 
m.getRuntime().getNil();
++        if (m.regs == null || m.regs.getBeg(0) == -1) return 
m.getRuntime().getNil();
+ 
+         int i;
+-        for (i = m.regs.numRegs - 1; m.regs.beg[i] == -1 && i > 0; i--);
++        for (i = m.regs.getNumRegs() - 1; m.regs.getBeg(i) == -1 && i > 0; 
i--)
+         if (i == 0) return m.getRuntime().getNil();
+ 
+         return nth_match(i, m);
+@@ -1757,8 +1757,8 @@ public class RubyRegexp extends RubyObject implements 
ReOptions, EncodingCapable
+                 continue;
+             case '+':
+                 if (regs != null) {
+-                    no = regs.numRegs - 1;
+-                    while (regs.beg[no] == -1 && no > 0) no--;
++                    no = regs.getNumRegs() - 1;
++                    while (regs.getBeg(no) == -1 && no > 0) no--;
+                 }
+                 if (no == 0) continue;
+                 break;
+@@ -1772,9 +1772,9 @@ public class RubyRegexp extends RubyObject implements 
ReOptions, EncodingCapable
+ 
+             if (regs != null) {
+                 if (no >= 0) {
+-                    if (no >= regs.numRegs) continue;
+-                    if (regs.beg[no] == -1) continue;
+-                    EncodingUtils.encStrBufCat(runtime, val, 
srcbs.getUnsafeBytes(), srcbs.getBegin() + regs.beg[no], regs.end[no] - 
regs.beg[no], srcEnc);
++                    if (no >= regs.getNumRegs()) continue;
++                    if (regs.getBeg(no) == -1) continue;
++                    EncodingUtils.encStrBufCat(runtime, val, 
srcbs.getUnsafeBytes(), srcbs.getBegin() + regs.getBeg(no), regs.getEnd(no) - 
regs.getBeg(no), srcEnc);
+                 }
+             } else {
+                 if (no != 0 || begin == -1) continue;
+diff --git a/core/src/main/java/org/jruby/RubyString.java 
b/core/src/main/java/org/jruby/RubyString.java
+index 98c470c..a8a468e 100644
+--- a/core/src/main/java/org/jruby/RubyString.java
++++ b/core/src/main/java/org/jruby/RubyString.java
+@@ -3843,7 +3843,7 @@ public class RubyString extends RubyObject implements 
CharSequence, EncodingCapa
+     }
+ 
+     private int subpatSetCheck(Ruby runtime, int nth, Region regs) {
+-        int numRegs = regs == null ? 1 : regs.numRegs;
++        int numRegs = regs == null ? 1 : regs.getNumRegs();
+         if (nth < numRegs) {
+             if (nth < 0) {
+                 if (-nth < numRegs) return nth + numRegs;
+@@ -3871,8 +3871,8 @@ public class RubyString extends RubyObject implements 
CharSequence, EncodingCapa
+             start = match.begin;
+             end = match.end;
+         } else {
+-            start = match.regs.beg[nth];
+-            end = match.regs.end[nth];
++            start = match.regs.getBeg(nth);
++            end = match.regs.getEnd(nth);
+         }
+         if (start == -1) throw runtime.newIndexError("regexp group " + nth + 
" not matched");
+         RubyString replStr =  repl.convertToString();
+diff --git a/core/src/main/java/org/jruby/ext/strscan/RubyStringScanner.java 
b/core/src/main/java/org/jruby/ext/strscan/RubyStringScanner.java
+index ac49149..c04ba7c 100644
+--- a/core/src/main/java/org/jruby/ext/strscan/RubyStringScanner.java
++++ b/core/src/main/java/org/jruby/ext/strscan/RubyStringScanner.java
+@@ -282,8 +282,8 @@ public class RubyStringScanner extends RubyObject {
+             this.beg = matcher.getBegin();
+             this.end = matcher.getEnd();
+         } else {
+-            this.beg = regs.beg[0];
+-            this.end = regs.end[0];
++            this.beg = regs.getBeg(0);
++            this.end = regs.getEnd(0);
+         }
+ 
+         if (ret < 0) return context.nil;
+@@ -524,7 +524,7 @@ public class RubyStringScanner extends RubyObject {
+             if (pattern == null) return context.nil;
+         }
+         int i = RubyMatchData.backrefNumber(runtime, pattern, regs, idx);
+-        int numRegs = regs == null ? 1 : regs.numRegs;
++        int numRegs = regs == null ? 1 : regs.getNumRegs();
+ 
+         if (i < 0) i += numRegs;
+         if (i < 0 || i >= numRegs) {
+@@ -536,8 +536,8 @@ public class RubyStringScanner extends RubyObject {
+             if (beg == -1) return context.nil;
+             return extractRange(runtime, lastPos + beg, lastPos + end);
+         } else {
+-            if (regs.beg[i] == -1) return context.nil;
+-            return extractRange(context.runtime, lastPos + regs.beg[i], 
lastPos + regs.end[i]);
++            if (regs.getBeg(i) == -1) return context.nil;
++            return extractRange(context.runtime, lastPos + regs.getBeg(i), 
lastPos + regs.getEnd(i));
+         }
+     }
+ 
+@@ -633,7 +633,7 @@ public class RubyStringScanner extends RubyObject {
+     @JRubyMethod(name = "size")
+     public IRubyObject size(ThreadContext context) {
+         if (!isMatched()) return context.nil;
+-        return context.runtime.newFixnum(regs.numRegs);
++        return context.runtime.newFixnum(regs.getNumRegs());
+     }
+ 
+     @JRubyMethod(name = "captures")
+@@ -645,12 +645,12 @@ public class RubyStringScanner extends RubyObject {
+ 
+         Ruby runtime = context.runtime;
+ 
+-        numRegs = regs.numRegs;
++        numRegs = regs.getNumRegs();
+         newAry  = RubyArray.newArray(runtime, numRegs);
+ 
+         for (i = 1; i < numRegs; i++) {
+-            IRubyObject str = extractRange(runtime, lastPos + regs.beg[i],
+-                    lastPos + regs.end[i]);
++            IRubyObject str = extractRange(runtime, lastPos + regs.getBeg(i),
++                    lastPos + regs.getEnd(i));
+             newAry.push(str);
+         }
+ 
diff -Nru 
jruby-9.3.9.0+ds/debian/patches/0013-Use-Region-factory-method-to-avoid-coupling.patch
 
jruby-9.3.9.0+ds/debian/patches/0013-Use-Region-factory-method-to-avoid-coupling.patch
--- 
jruby-9.3.9.0+ds/debian/patches/0013-Use-Region-factory-method-to-avoid-coupling.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
jruby-9.3.9.0+ds/debian/patches/0013-Use-Region-factory-method-to-avoid-coupling.patch
      2023-11-24 11:48:05.000000000 +0000
@@ -0,0 +1,25 @@
+Subject: Use Region factory method to avoid coupling
+Forwarded: 
https://github.com/jruby/jruby/commit/783d14bcb140477bb2577310a90742d594a48896
+--
+diff --git a/core/src/main/java/org/jruby/RubyMatchData.java 
b/core/src/main/java/org/jruby/RubyMatchData.java
+index 87e7c9d..ccc5294 100644
+--- a/core/src/main/java/org/jruby/RubyMatchData.java
++++ b/core/src/main/java/org/jruby/RubyMatchData.java
+@@ -175,7 +175,7 @@ public class RubyMatchData extends RubyObject {
+     private void updateCharOffsetOnlyOneReg(ByteList value, Encoding 
encoding) {
+         if (charOffsetUpdated) return;
+ 
+-        if (charOffsets == null || charOffsets.getNumRegs() < 1) charOffsets 
= new Region(1);
++        if (charOffsets == null || charOffsets.getNumRegs() < 1) charOffsets 
= Region.newRegion(1);
+ 
+         if (encoding.maxLength() == 1) {
+             charOffsets.setBeg(0, begin);
+@@ -213,7 +213,7 @@ public class RubyMatchData extends RubyObject {
+         final Region regs = this.regs;
+         int numRegs = regs.getNumRegs();
+ 
+-        if (charOffsets == null || charOffsets.getNumRegs() < numRegs) 
charOffsets = new Region(numRegs);
++        if (charOffsets == null || charOffsets.getNumRegs() < numRegs) 
charOffsets = Region.newRegion(numRegs);
+ 
+         if (encoding.maxLength() == 1) {
+             for (int i = 0; i < numRegs; i++) {
diff -Nru jruby-9.3.9.0+ds/debian/patches/series 
jruby-9.3.9.0+ds/debian/patches/series
--- jruby-9.3.9.0+ds/debian/patches/series      2023-01-16 21:08:51.000000000 
+0000
+++ jruby-9.3.9.0+ds/debian/patches/series      2023-11-24 11:48:05.000000000 
+0000
@@ -9,3 +9,5 @@
 0010-Fix-test-failures-related-to-Module-PTY.patch
 0011-Remove-failing-test-in-build-environment.patch
 0011-Fix-intermittent-mri-core-test-failure.patch
+0012-Use-Region-accessors-in-prep-for-privatizing-fields.patch
+0013-Use-Region-factory-method-to-avoid-coupling.patch

Reply via email to