Skip to content

Commit e75195e

Browse files
committed
S_parse_ident: Restructure croaks
This removes the test for the identifier being too long at the beginning of the loop. Almost all the branches already have their own checks for this, and by restructuring those slightly, this one becomes extraneous, except for the one branch that didn't have a check. And it turns out this was wrong for that branch, which is the one that turns an apostrophe package separator into ::. The removed code assumed that the output doesn't expand, whereas each single apostrophe is in fact replaced by two characters. This commit corrects that. And it consolidates the handling to the target of a goto at the end of the function. Right now, there is no real advantage in that, but a future commit will make the handling more complicated, so a single point for it will be useful.
1 parent ec82a31 commit e75195e

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

toke.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10579,8 +10579,6 @@ S_parse_ident(pTHX_ const char *s, const char * const s_end,
1057910579
const bool check_dollar = flags & CHECK_DOLLAR;
1058010580

1058110581
while (s < s_end) {
10582-
if (*d >= e)
10583-
croak("%s", ident_too_long);
1058410582

1058510583
/* For non-UTF8, variables that match ASCII \w are a superset of
1058610584
* variables that start with IDFIRST, so we have to look at the
@@ -10600,8 +10598,9 @@ S_parse_ident(pTHX_ const char *s, const char * const s_end,
1060010598

1060110599
/* Here we have found the end of the identifier */
1060210600
Size_t this_length = t - s;
10603-
if (*d + this_length > e)
10604-
croak("%s", ident_too_long);
10601+
if (*d + this_length >= e) {
10602+
goto too_long;
10603+
}
1060510604

1060610605
/* And copy the whole thing in one operation */
1060710606
Copy(s, *d, this_length, char);
@@ -10614,13 +10613,21 @@ S_parse_ident(pTHX_ const char *s, const char * const s_end,
1061410613
* digit */
1061510614
do {
1061610615
*(*d)++ = *s++;
10617-
} while (isWORDCHAR_A(*s) && *d < e);
10616+
10617+
if (*d >= e) {
10618+
goto too_long;
10619+
}
10620+
} while (isWORDCHAR_A(*s));
1061810621
}
1061910622
else if ( allow_package
1062010623
&& *s == '\''
1062110624
&& FEATURE_APOS_AS_NAME_SEP_IS_ENABLED
1062210625
&& isIDFIRST_lazy_if_safe(s + 1, s_end, is_utf8))
1062310626
{ /* Convert the apostrophe to "::" */
10627+
if (*d >= e - 2) {
10628+
goto too_long;
10629+
}
10630+
1062410631
*(*d)++ = ':';
1062510632
*(*d)++ = ':';
1062610633
s++;
@@ -10632,6 +10639,10 @@ S_parse_ident(pTHX_ const char *s, const char * const s_end,
1063210639
*/
1063310640
&& !(check_dollar && s[2] == '$'))
1063410641
{
10642+
if (*d >= e - 2) {
10643+
goto too_long;
10644+
}
10645+
1063510646
*(*d)++ = *s++;
1063610647
*(*d)++ = *s++;
1063710648
}
@@ -10646,6 +10657,9 @@ S_parse_ident(pTHX_ const char *s, const char * const s_end,
1064610657
* function declares it as const so as to indicate that it doesn't change
1064710658
* it, and it can be called using a const parameter */
1064810659
return (char *) s;
10660+
10661+
too_long:
10662+
croak("%s", ident_too_long);
1064910663
}
1065010664

1065110665
char *

0 commit comments

Comments
 (0)