This is an automated email from the git hooks/post-receive script. henrich pushed a commit to branch debian/sid in repository jruby-joni.
commit e0323eea7ae6c403d5d384520081731f9af283f4 Author: Marcin Mielzynski <[email protected]> Date: Wed Aug 17 02:54:15 2016 +0200 fix for jruby/jruby#4077 --- src/org/joni/Analyser.java | 21 +++-- src/org/joni/Config.java | 2 + src/org/joni/Lexer.java | 168 ++++++++++++++++++++++---------------- src/org/joni/Parser.java | 18 +++- src/org/joni/ScanEnvironment.java | 7 +- src/org/joni/StackMachine.java | 25 +++--- src/org/joni/Token.java | 7 ++ 7 files changed, 151 insertions(+), 97 deletions(-) diff --git a/src/org/joni/Analyser.java b/src/org/joni/Analyser.java index 6a4e418..ddb0f5c 100644 --- a/src/org/joni/Analyser.java +++ b/src/org/joni/Analyser.java @@ -1277,7 +1277,6 @@ final class Analyser extends Parser { case NodeType.CALL: CallNode cn = (CallNode)node; - if (cn.groupNum != 0) { int gNum = cn.groupNum; @@ -1290,15 +1289,19 @@ final class Analyser extends Parser { setCallAttr(cn); } else { if (Config.USE_NAMED_GROUP) { - NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd); - - if (ne == null) { - newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd); - } else if (ne.backNum > 1) { - newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd); - } else { - cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ? + if (Config.USE_PERL_SUBEXP_CALL && cn.nameP == cn.nameEnd) { setCallAttr(cn); + } else { + NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd); + + if (ne == null) { + newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd); + } else if (ne.backNum > 1) { + newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd); + } else { + cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ? + setCallAttr(cn); + } } } } diff --git a/src/org/joni/Config.java b/src/org/joni/Config.java index 3467966..30f3871 100644 --- a/src/org/joni/Config.java +++ b/src/org/joni/Config.java @@ -23,9 +23,11 @@ import java.io.PrintStream; public interface Config extends org.jcodings.Config { final int CHAR_TABLE_SIZE = 256; + final int SCANENV_MEMNODES_SIZE = 8; final boolean USE_NAMED_GROUP = true; final boolean USE_SUBEXP_CALL = true; + final boolean USE_PERL_SUBEXP_CALL = true; final boolean USE_BACKREF_WITH_LEVEL = true; /* \k<name+n>, \k<name-n> */ final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */ diff --git a/src/org/joni/Lexer.java b/src/org/joni/Lexer.java index c1feb68..812369f 100644 --- a/src/org/joni/Lexer.java +++ b/src/org/joni/Lexer.java @@ -851,94 +851,122 @@ class Lexer extends ScannerSupport { } } - private void fetchTokenFor_namedBackref() { - if (syntax.op2EscKNamedBackref()) { - if (left()) { + private void fetchTokenFor_NamedBackref() { + if (Config.USE_NAMED_GROUP) { + if (syntax.op2EscKNamedBackref() && left()) { fetch(); if (c =='<' || c == '\'') { - int last = p; - int backNum; - if (Config.USE_BACKREF_WITH_LEVEL) { - Ptr rbackNum = new Ptr(); - Ptr rlevel = new Ptr(); - token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel)); - token.setBackrefLevel(rlevel.p); - backNum = rbackNum.p; - } else { - backNum = fetchName(c, true); - } // USE_BACKREF_AT_LEVEL - int nameEnd = value; // set by fetchNameWithLevel/fetchName - - if (backNum != 0) { - if (backNum < 0) { - backNum = backrefRelToAbs(backNum); - if (backNum <= 0) newValueException(ERR_INVALID_BACKREF); - } - - if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) { - newValueException(ERR_INVALID_BACKREF); - } - token.type = TokenType.BACKREF; - token.setBackrefByName(false); - token.setBackrefNum(1); - token.setBackrefRef1(backNum); - } else { - NameEntry e = env.reg.nameToGroupNumbers(bytes, last, nameEnd); - if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd); - - if (syntax.strictCheckBackref()) { - if (e.backNum == 1) { - if (e.backRef1 > env.numMem || - env.memNodes == null || - env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF); - } else { - for (int i=0; i<e.backNum; i++) { - if (e.backRefs[i] > env.numMem || - env.memNodes == null || - env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF); - } - } - } - - token.type = TokenType.BACKREF; - token.setBackrefByName(true); - - if (e.backNum == 1) { - token.setBackrefNum(1); - token.setBackrefRef1(e.backRef1); - } else { - token.setBackrefNum(e.backNum); - token.setBackrefRefs(e.backRefs); - } - } + fetchNamedBackrefToken(); } else { unfetch(); syntaxWarn(Warnings.INVALID_BACKREFERENCE); } - } else { - syntaxWarn(Warnings.INVALID_BACKREFERENCE); } } } private void fetchTokenFor_subexpCall() { - if (syntax.op2EscGSubexpCall()) { - if (left()) { + if (Config.USE_NAMED_GROUP) { + if (syntax.op2EscGBraceBackref() && left()) { + fetch(); + if (c == '{') { + fetchNamedBackrefToken(); + } else { + unfetch(); + } + } + } + if (Config.USE_SUBEXP_CALL) { + if (syntax.op2EscGSubexpCall() && left()) { fetch(); if (c == '<' || c == '\'') { - int last = p; - int gNum = fetchName(c, true); - int nameEnd = value; + int gNum = -1; + boolean rel = false; + int cnext = peek(); + int nameEnd = 0; + if (cnext == '0') { + inc(); + if (peekIs(nameEndCodePoint(c))) { /* \g<0>, \g'0' */ + inc(); + nameEnd = p; + gNum = 0; + } + } else if (cnext == '+') { + inc(); + rel = true; + } + int prev = p; + if (gNum < 0) { + gNum = fetchName(c, true); + nameEnd = value; + } token.type = TokenType.CALL; - token.setCallNameP(last); + token.setCallNameP(prev); token.setCallNameEnd(nameEnd); token.setCallGNum(gNum); + token.setCallRel(rel); } else { - unfetch(); syntaxWarn(Warnings.INVALID_SUBEXP_CALL); + unfetch(); } + } + } + } + + private void fetchNamedBackrefToken() { + int last = p; + int backNum; + if (Config.USE_BACKREF_WITH_LEVEL) { + Ptr rbackNum = new Ptr(); + Ptr rlevel = new Ptr(); + token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel)); + token.setBackrefLevel(rlevel.p); + backNum = rbackNum.p; + } else { + backNum = fetchName(c, true); + } // USE_BACKREF_AT_LEVEL + int nameEnd = value; // set by fetchNameWithLevel/fetchName + + if (backNum != 0) { + if (backNum < 0) { + backNum = backrefRelToAbs(backNum); + if (backNum <= 0) newValueException(ERR_INVALID_BACKREF); + } + + if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) { + newValueException(ERR_INVALID_BACKREF); + } + token.type = TokenType.BACKREF; + token.setBackrefByName(false); + token.setBackrefNum(1); + token.setBackrefRef1(backNum); + } else { + NameEntry e = env.reg.nameToGroupNumbers(bytes, last, nameEnd); + if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd); + + if (syntax.strictCheckBackref()) { + if (e.backNum == 1) { + if (e.backRef1 > env.numMem || + env.memNodes == null || + env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF); + } else { + for (int i=0; i<e.backNum; i++) { + if (e.backRefs[i] > env.numMem || + env.memNodes == null || + env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF); + } + } + } + + token.type = TokenType.BACKREF; + token.setBackrefByName(true); + + if (e.backNum == 1) { + token.setBackrefNum(1); + token.setBackrefRef1(e.backRef1); } else { - syntaxWarn(Warnings.INVALID_SUBEXP_CALL); + token.setBackrefNum(e.backNum); + token.setBackrefRefs(e.backRefs); } } } @@ -1110,10 +1138,10 @@ class Lexer extends ScannerSupport { fetchTokenFor_zero(); break; case 'k': - if (Config.USE_NAMED_GROUP) fetchTokenFor_namedBackref(); + fetchTokenFor_NamedBackref(); break; case 'g': - if (Config.USE_SUBEXP_CALL) fetchTokenFor_subexpCall(); + fetchTokenFor_subexpCall(); break; case 'Q': if (syntax.op2EscCapitalQQuote()) token.type = TokenType.QUOTE_OPEN; diff --git a/src/org/joni/Parser.java b/src/org/joni/Parser.java index e480afd..81f635c 100644 --- a/src/org/joni/Parser.java +++ b/src/org/joni/Parser.java @@ -950,8 +950,8 @@ class Parser extends Lexer { case CALL: if (Config.USE_SUBEXP_CALL) { int gNum = token.getCallGNum(); - - if (gNum < 0) { + if (gNum < 0 || token.getCallRel()) { + if (gNum > 0) gNum--; gNum = backrefRelToAbs(gNum); if (gNum <= 0) newValueException(ERR_INVALID_BACKREF); } @@ -1163,6 +1163,18 @@ class Parser extends Lexer { private Node parseRegexp() { fetchToken(); - return parseSubExp(TokenType.EOT); + Node top = parseSubExp(TokenType.EOT); + if (Config.USE_SUBEXP_CALL) { + if (env.numCall > 0) { + /* Capture the pattern itself. It is used for (?R), (?0) and \g<0>. */ + EncloseNode np = new EncloseNode(env.option, false); + np.regNum = 0; + np.setTarget(top); + if (env.memNodes == null) env.memNodes = new Node[Config.SCANENV_MEMNODES_SIZE]; + env.memNodes[0] = np; + top = np; + } + } + return top; } } diff --git a/src/org/joni/ScanEnvironment.java b/src/org/joni/ScanEnvironment.java index 0dbce24..4c68a04 100644 --- a/src/org/joni/ScanEnvironment.java +++ b/src/org/joni/ScanEnvironment.java @@ -27,9 +27,6 @@ import org.joni.exception.ErrorMessages; import org.joni.exception.InternalException; public final class ScanEnvironment { - - private static final int SCANENV_MEMNODES_SIZE = 8; - int option; final int caseFoldFlag; final public Encoding enc; @@ -90,7 +87,7 @@ public final class ScanEnvironment { public int addMemEntry() { if (numMem++ == 0) { - memNodes = new Node[SCANENV_MEMNODES_SIZE]; + memNodes = new Node[Config.SCANENV_MEMNODES_SIZE]; } else if (numMem >= memNodes.length) { Node[]tmp = new Node[memNodes.length << 1]; System.arraycopy(memNodes, 0, tmp, 0, memNodes.length); @@ -111,7 +108,7 @@ public final class ScanEnvironment { public void pushPrecReadNotNode(Node node) { numPrecReadNotNodes++; if (precReadNotNodes == null) { - precReadNotNodes = new Node[SCANENV_MEMNODES_SIZE]; + precReadNotNodes = new Node[Config.SCANENV_MEMNODES_SIZE]; } else if (numPrecReadNotNodes >= precReadNotNodes.length) { Node[]tmp = new Node[precReadNotNodes.length << 1]; System.arraycopy(precReadNotNodes, 0, tmp, 0, precReadNotNodes.length); diff --git a/src/org/joni/StackMachine.java b/src/org/joni/StackMachine.java index 07e5e04..d5210ca 100644 --- a/src/org/joni/StackMachine.java +++ b/src/org/joni/StackMachine.java @@ -42,15 +42,20 @@ abstract class StackMachine extends Matcher implements StackType { protected StackMachine(Regex regex, byte[]bytes, int p , int end) { super(regex, bytes, p, end); - - this.stack = regex.requireStack ? fetchStack() : null; - int n = regex.numRepeat + (regex.numMem << 1); - this.repeatStk = n > 0 ? new int[n] : null; - - memStartStk = regex.numRepeat - 1; - memEndStk = memStartStk + regex.numMem; - /* for index start from 1, mem_start_stk[1]..mem_start_stk[num_mem] */ - /* for index start from 1, mem_end_stk[1]..mem_end_stk[num_mem] */ + stack = regex.requireStack ? fetchStack() : null; + final int n; + if (Config.USE_SUBEXP_CALL) { + n = regex.numRepeat + ((regex.numMem + 1) << 1); + memStartStk = regex.numRepeat; + memEndStk = memStartStk + regex.numMem + 1; + } else { + n = regex.numRepeat + (regex.numMem << 1); + memStartStk = regex.numRepeat - 1; + memEndStk = memStartStk + regex.numMem; + /* for index start from 1, mem_start_stk[1]..mem_start_stk[num_mem] */ + /* for index start from 1, mem_end_stk[1]..mem_end_stk[num_mem] */ + } + repeatStk = n > 0 ? new int[n] : null; } private static StackEntry[] allocateStack() { @@ -86,7 +91,7 @@ abstract class StackMachine extends Matcher implements StackType { protected final void init() { if (stack != null) pushEnsured(ALT, regex.codeLength - 1); /* bottom stack */ if (repeatStk != null) { - for (int i=1; i<=regex.numMem; i++) { + for (int i = (Config.USE_SUBEXP_CALL ? 0 : 1); i <= regex.numMem; i++) { repeatStk[i + memStartStk] = repeatStk[i + memEndStk] = INVALID_INDEX; } } diff --git a/src/org/joni/Token.java b/src/org/joni/Token.java index 321ad91..c57662e 100644 --- a/src/org/joni/Token.java +++ b/src/org/joni/Token.java @@ -156,6 +156,13 @@ final class Token { INT3 = gnum; } + boolean getCallRel() { + return INT4 != 0; + } + void setCallRel(boolean rel) { + INT4 = rel ? 1 : 0; + } + // prop union member int getPropCType() { return INT1; -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jruby-joni.git _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

