PATCH: [perl #116899]: jump on uninitialised value
authorKarl Williamson <public@khwilliamson.com>
Fri, 22 Feb 2013 20:04:05 +0000 (13:04 -0700)
committerKarl Williamson <public@khwilliamson.com>
Fri, 22 Feb 2013 20:29:16 +0000 (13:29 -0700)
The culprit had nothing to do really with the accuesed commit.
The function S_cl_or() tries to take the union of the code points
matched by its two inputs.  Both of those nodes must be ANYOF-like
(for bracketed character classes and synthetic start classes).  These
come in two flavors, one having extra fields in the struct after the
other one's.  That is used for locale ANYOFs and the synthetic start
class.  The first paramter to cl_or() is always one of these extended
ANYOFS, but the second parameter may be the shorter form

The function was failing to check if the second one was the longer form
before reading data from beyond the short-form's struct.  This could
cause a segfault, but that wasn't the symptom here.  Instead it copied
that data to the other paramter's struct.  valgrind had set that data to
indicate it was uninitialized, so when later it was accessed, we got
this error.

During much of the 5.17 series until the failing commit, more ANYOF
nodes were the larger size.  I presume that is why this commit showed up
the problem.

regcomp.c

index 71084f1..d8260e2 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -1028,7 +1028,9 @@ S_cl_or(const RExC_state_t *pRExC_state, struct regnode_charclass_class *cl, con
            /* OR char bitmap and class bitmap separately */
            for (i = 0; i < ANYOF_BITMAP_SIZE; i++)
                cl->bitmap[i] |= or_with->bitmap[i];
-            ANYOF_CLASS_OR(or_with, cl);
+            if (or_with->flags & ANYOF_CLASS) {
+                ANYOF_CLASS_OR(or_with, cl);
+            }
        }
        else { /* XXXX: logic is complicated, leave it along for a moment. */
            cl_anything(pRExC_state, cl);