This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
INSTALL - document how to build a perl without taint support
[perl5.git] / pp_pack.c
index 41f72b7..4442287 100644 (file)
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -541,22 +541,24 @@ STATIC const char *
 S_group_end(pTHX_ const char *patptr, const char *patend, char ender)
 {
     PERL_ARGS_ASSERT_GROUP_END;
+    Size_t opened = 0;  /* number of pending opened brackets */
 
     while (patptr < patend) {
         const char c = *patptr++;
 
-        if (isSPACE(c))
-            continue;
-        else if (c == ender)
+        if (opened == 0 && c == ender)
             return patptr-1;
         else if (c == '#') {
             while (patptr < patend && *patptr != '\n')
                 patptr++;
             continue;
-        } else if (c == '(')
-            patptr = group_end(patptr, patend, ')') + 1;
-        else if (c == '[')
-            patptr = group_end(patptr, patend, ']') + 1;
+        } else if (c == '(' || c == '[')
+            ++opened;
+        else if (c == ')' || c == ']') {
+            if (opened == 0)
+                Perl_croak(aTHX_ "Mismatched brackets in template");
+            --opened;
+        }
     }
     Perl_croak(aTHX_ "No group ending character '%c' found in template",
                ender);
@@ -937,6 +939,7 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, const char *s, const char *strbeg, const c
             const U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
             symptr->flags |= group_modifiers;
             symptr->patend = savsym.grpend;
+            /* cppcheck-suppress autoVariables */
             symptr->previous = &savsym;
             symptr->level++;
             PUTBACK;
@@ -2247,6 +2250,7 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
             symptr->flags |= group_modifiers;
             symptr->patend = savsym.grpend;
             symptr->level++;
+            /* cppcheck-suppress autoVariables */
             symptr->previous = &lookahead;
             while (len--) {
                 U32 was_utf8;