From 5fbab17c47c4f3993fd74eb81931eb628bf0473c Mon Sep 17 00:00:00 2001 From: Dmitry Olshansky Date: Thu, 24 Aug 2017 14:20:22 +0300 Subject: [PATCH] Fix issue 17673 - wrong whichPattern in multi-regex with alteration --- std/regex/internal/tests.d | 16 ++++++++++++++-- std/regex/package.d | 8 +++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/std/regex/internal/tests.d b/std/regex/internal/tests.d index 1d4f9a26ae6..e93ac9caba7 100644 --- a/std/regex/internal/tests.d +++ b/std/regex/internal/tests.d @@ -1087,10 +1087,10 @@ alias Sequence(int B, int E) = staticIota!(B, E); @safe unittest { import std.algorithm.searching : canFind; - void willThrow(T)(T arg, string msg) + void willThrow(T, size_t line = __LINE__)(T arg, string msg) { auto e = collectException(regex(arg)); - assert(e.msg.canFind(msg), e.msg); + assert(e.msg.canFind(msg), to!string(line) ~ ": " ~ e.msg); } willThrow([r".", r"[\(\{[\]\}\)]"], "no matching ']' found while parsing character class"); willThrow([r"[\", r"123"], "no matching ']' found while parsing character class"); @@ -1106,3 +1106,15 @@ alias Sequence(int B, int E) = staticIota!(B, E); auto e = collectException!RegexException(regex(q"<[^]>")); assert(e.msg.canFind("no operand for '^'")); } + +// bugzilla 17673 +@safe unittest +{ + string str = `<">`; + string[] regexps = ["abc", "\"|x"]; + auto regexp = regex(regexps); + auto c = matchFirst(str, regexp); + assert(c); + assert(c.whichPattern == 2); +} + diff --git a/std/regex/package.d b/std/regex/package.d index d61514c719f..bfc7d7ff30b 100644 --- a/std/regex/package.d +++ b/std/regex/package.d @@ -374,9 +374,15 @@ if (isSomeString!(S)) app.put("|"); app.put("(?:"); app.put(patterns[i]); + // terminator for the pattern + // to detect if the pattern unexpectedly ends app.put("\\"); - app.put(cast(dchar)(privateUseStart+i)); // special end marker + app.put(cast(dchar)(privateUseStart+i)); app.put(")"); + // another one to return correct whichPattern + // for all of potential alternatives in the patterns[i] + app.put("\\"); + app.put(cast(dchar)(privateUseStart+i)); } pat = app.data; }