From 829414f8e549fe7e4b1a6696ca70664e89e5e7f0 Mon Sep 17 00:00:00 2001
From: Nicholas Wilson <niwilson@microsoft.com>
Date: Wed, 18 Sep 2024 16:39:22 +0100
Subject: [PATCH] Fix incorrect positive error code from pcre2_substitute()
 (#481)

---
 src/pcre2_substitute.c |  4 +++-
 testdata/testinput2    |  6 ++++++
 testdata/testoutput2   | 10 ++++++++++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/pcre2_substitute.c b/src/pcre2_substitute.c
index 86c1d1e69..862ea9f73 100644
--- a/src/pcre2_substitute.c
+++ b/src/pcre2_substitute.c
@@ -134,7 +134,9 @@ for (; ptr < ptrend; ptr++)
     ptr -= 1;  /* Back to last code unit of escape */
     if (errorcode != 0)
       {
-      rc = errorcode;
+      /* errorcode from check_escape is positive, so must not be returned by
+      pcre2_substitute(). */
+      rc = PCRE2_ERROR_BADREPESCAPE;
       goto EXIT;
       }
 
diff --git a/testdata/testinput2 b/testdata/testinput2
index c2abdb890..8be78ff50 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -4201,6 +4201,12 @@
     123abc123\=substitute_overflow_length,replace=[1]x$1z
     123abc123\=substitute_overflow_length,replace=[0]x$1z
 
+/a(b)c/substitute_extended
+    ZabcZ\=replace=>${1:+ yes : no }
+    ZabcZ\=replace=>${1:+ \o{100} : \o{100} }
+    ZabcZ\=replace=>${1:+ \o{Z} : no }
+    ZabcZ\=replace=>${1:+ yes : \o{Z} }
+
 "((?=(?(?=(?(?=(?(?=()))))))))"
     a
 
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index 7a582cd23..ccf209b5c 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -13818,6 +13818,16 @@ Failed: error -48: no more memory: 10 code units are needed
     123abc123\=substitute_overflow_length,replace=[0]x$1z
 Failed: error -48: no more memory: 10 code units are needed
 
+/a(b)c/substitute_extended
+    ZabcZ\=replace=>${1:+ yes : no }
+ 1: Z> yes Z
+    ZabcZ\=replace=>${1:+ \o{100} : \o{100} }
+ 1: Z> @ Z
+    ZabcZ\=replace=>${1:+ \o{Z} : no }
+Failed: error -57 at offset 9 in replacement: bad escape sequence in replacement string
+    ZabcZ\=replace=>${1:+ yes : \o{Z} }
+Failed: error -57 at offset 15 in replacement: bad escape sequence in replacement string
+
 "((?=(?(?=(?(?=(?(?=()))))))))"
     a
  0: 
