regcomp.c: Add ability to not warn during substitute parse
authorKarl Williamson <khw@cpan.org>
Sun, 14 Oct 2018 18:01:07 +0000 (12:01 -0600)
committerKarl Williamson <khw@cpan.org>
Sat, 20 Oct 2018 06:09:55 +0000 (00:09 -0600)
Under certain conditions, regcomp.c will pretend something other than
the input pattern is to be parsed.  There is a mechanism to seamlessly
show the original code when that substitute expression contains the
original as a subset.  But there are cases where the entire substitute
is constructed by regcomp.c, and has none of the original pattern in
it.  Since it is our construction, it should be legal, devoid of
warnings, but if somehow something happened to generate a warning, it
could lead to seg faults, etc.

This commit adds and uses a mechanism to turn off warnings while parsing
these constructs.  Should a warning attempt to be output, instead of a
seg fault, a panic error message giving debugging details is output.

regcomp.c

index 7d3e0d8..668f264 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -791,17 +791,27 @@ static const scan_data_t zero_scan_data = {
             REPORT_LOCATION_ARGS(RExC_parse));          \
 } STMT_END
 
+/* Setting this to NULL is a signal to not output warnings */
+#define TURN_OFF_WARNINGS_IN_SUBSTITUTE_PARSE RExC_copy_start_in_constructed = NULL
+#define RESTORE_WARNINGS RExC_copy_start_in_constructed = RExC_precomp
+
 /* Outputting warnings is generally deferred until the 2nd pass.  This is
  * because the first pass can be restarted, for example if the pattern has to
  * be converted to UTF-8.  If a warning had already been output earlier in the
  * pass, it would be re-output after the restart.  Pass 2 is never restarted,
  * so the problem simply goes away if we defer the output to that pass.  See
- * [perl #122671]. */
+ * [perl #122671]. 'RExC_copy_start_in_constructed' being NULL is a flag to
+ * not generate any warnings */
 #define TO_OUTPUT_WARNINGS(loc)                                         \
-  cBOOL(PASS2)
+  (PASS2 && RExC_copy_start_in_constructed)
 
 #define _WARN_HELPER(loc, warns, code)                                  \
     STMT_START {                                                        \
+        if (! RExC_copy_start_in_constructed) {                         \
+            Perl_croak( aTHX_ "panic! %s: %d: Tried to warn when none"  \
+                              " expected at '%s'",                      \
+                              __FILE__, __LINE__, loc);                 \
+        }                                                               \
         if (TO_OUTPUT_WARNINGS(loc)) {                                  \
             code;                                                       \
         }                                                               \
@@ -12619,17 +12629,19 @@ S_grok_bslash_N(pTHX_ RExC_state_t *pRExC_state,
      * The error reporting mechanism doesn't work for 2 levels of this, but the
      * code above has validated this new construct, so there should be no
      * errors generated by the below.  And this isn' an exact copy, so the
-     * mechanism to seamlessly deal with this won't work.  XXX Maybe should
-     * turn off all warnings for safety? */
+     * mechanism to seamlessly deal with this won't work, so turn off warnings
+     * during it */
     save_start = RExC_start;
     orig_end = RExC_end;
 
     RExC_parse = RExC_start = SvPVX(substitute_parse);
     RExC_end = RExC_parse + SvCUR(substitute_parse);
+    TURN_OFF_WARNINGS_IN_SUBSTITUTE_PARSE;
 
     *node_p = reg(pRExC_state, 1, &flags, depth+1);
 
     /* Restore the saved values */
+    RESTORE_WARNINGS;
     RExC_start = save_start;
     RExC_parse = endbrace;
     RExC_end = orig_end;
@@ -16088,6 +16100,7 @@ redo_curchar:
     RExC_parse = SvPV(result_string, len);
     save_end = RExC_end;
     RExC_end = RExC_parse + len;
+    TURN_OFF_WARNINGS_IN_SUBSTITUTE_PARSE;
 
     /* We turn off folding around the call, as the class we have constructed
      * already has all folding taken into consideration, and we don't want
@@ -16107,6 +16120,7 @@ redo_curchar:
                     NULL
                 );
 
+    RESTORE_WARNINGS;
     RExC_parse = save_parse + 1;
     RExC_end = save_end;
     SvREFCNT_dec_NN(final);