@@ -5511,12 +5511,19 @@ S_compute_EXACTish(RExC_state_t *pRExC_state)
5511
5511
* in which case return I32_MAX (rather than possibly 32-bit wrapping) */
5512
5512
5513
5513
static I32
5514
- S_backref_value(char *p, char *e)
5514
+ S_backref_value(const char *p, const char *e, char **pe )
5515
5515
{
5516
- const char* endptr = e;
5516
+ const char * endptr = e;
5517
5517
UV val;
5518
- if (grok_atoUV(p, &val, &endptr) && val <= I32_MAX)
5518
+ if (grok_atoUV(p, &val, &endptr) && val <= I32_MAX) {
5519
+ if (pe) {
5520
+ *pe = (char *)endptr;
5521
+ }
5519
5522
return (I32)val;
5523
+ }
5524
+ if (pe) {
5525
+ *pe = NULL;
5526
+ }
5520
5527
return I32_MAX;
5521
5528
}
5522
5529
@@ -6021,7 +6028,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6021
6028
char * e = RExC_end;
6022
6029
6023
6030
if (*s == 'g') {
6024
- bool isrel = 0 ;
6031
+ bool isrel = FALSE ;
6025
6032
6026
6033
s++;
6027
6034
if (*s == '{') {
@@ -6067,7 +6074,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6067
6074
* surrounding braces */
6068
6075
6069
6076
if (*s == '-') {
6070
- isrel = 1 ;
6077
+ isrel = TRUE ;
6071
6078
s++;
6072
6079
}
6073
6080
@@ -6076,7 +6083,20 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6076
6083
}
6077
6084
6078
6085
RExC_parse_set(s);
6079
- num = S_backref_value(RExC_parse, RExC_end);
6086
+ num = S_backref_value(RExC_parse, RExC_end, &s);
6087
+
6088
+ if (endbrace && s) {
6089
+ while (isBLANK(*s)) {
6090
+ ++s;
6091
+ }
6092
+ assert(s <= endbrace);
6093
+ if (s != endbrace) {
6094
+ RExC_parse_set(s);
6095
+ vFAIL2("Sequence \\%s... not terminated", "g{");
6096
+ }
6097
+ ++s;
6098
+ }
6099
+
6080
6100
if (num == 0)
6081
6101
vFAIL("Reference to invalid group 0");
6082
6102
else if (num == I32_MAX) {
@@ -6085,6 +6105,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6085
6105
else
6086
6106
vFAIL("Unterminated \\g... pattern");
6087
6107
}
6108
+ assert(s != NULL);
6088
6109
6089
6110
if (isrel) {
6090
6111
num = RExC_npar - num;
@@ -6108,7 +6129,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6108
6129
}
6109
6130
}
6110
6131
else {
6111
- num = S_backref_value(RExC_parse, RExC_end);
6132
+ num = S_backref_value(RExC_parse, RExC_end, &s );
6112
6133
/* bare \NNN might be backref or octal - if it is larger
6113
6134
* than or equal RExC_npar then it is assumed to be an
6114
6135
* octal escape. Note RExC_npar is +1 from the actual
@@ -6131,6 +6152,12 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6131
6152
RExC_parse_set(atom_parse_start);
6132
6153
goto defchar;
6133
6154
}
6155
+
6156
+ if (!s) {
6157
+ for (s = RExC_parse; isDIGIT(*s); ++s)
6158
+ ;
6159
+ }
6160
+
6134
6161
if (num < RExC_logical_npar) {
6135
6162
num = RExC_logical_to_parno[num];
6136
6163
}
@@ -6154,12 +6181,8 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6154
6181
*
6155
6182
* We've already figured out what value the digits represent.
6156
6183
* Now, move the parse to beyond them. */
6157
- if (endbrace) {
6158
- RExC_parse_set(endbrace + 1);
6159
- }
6160
- else while (isDIGIT(*RExC_parse)) {
6161
- RExC_parse_inc_by(1);
6162
- }
6184
+ assert(s != NULL);
6185
+ RExC_parse_set(s);
6163
6186
if (num < 0)
6164
6187
vFAIL("Reference to nonexistent group");
6165
6188
@@ -6577,7 +6600,7 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
6577
6600
/* NOTE, RExC_npar is 1 more than the actual number of
6578
6601
* parens we have seen so far, hence the "<" as opposed
6579
6602
* to "<=" */
6580
- if ( !isDIGIT(p[1]) || S_backref_value(p, RExC_end) < RExC_npar)
6603
+ if ( !isDIGIT(p[1]) || S_backref_value(p, RExC_end, NULL ) < RExC_npar)
6581
6604
{ /* Not to be treated as an octal constant, go
6582
6605
find backref */
6583
6606
p = oldp;
0 commit comments