This allows \x and \o to work properly in the face of embedded NULs.
A limit parameter is added to each function, and that is passed to
memchr (which replaces strchr). See the branch merge message for more
information.
}
bool
-Perl_grok_bslash_o(pTHX_ char **s, UV *uv, const char** error_msg,
+Perl_grok_bslash_o(pTHX_ char **s, const char * const send, UV *uv,
+ const char** error_msg,
const bool output_warning, const bool strict,
const bool silence_non_portable,
const bool UTF)
* It guarantees that the returned codepoint, *uv, when expressed as
* utf8 bytes, would fit within the skipped "\o{...}" bytes.
* On input:
- * s is the address of a pointer to a NULL terminated string that begins
- * with 'o', and the previous character was a backslash. At exit, *s
- * will be advanced to the byte just after those absorbed by this
- * function. Hence the caller can continue parsing from there. In
- * the case of an error, this routine has generally positioned *s to
- * point just to the right of the first bad spot, so that a message
- * that has a "<--" to mark the spot will be correctly positioned.
+ * s is the address of a pointer to a string. **s is 'o', and the
+ * previous character was a backslash. At exit, *s will be advanced
+ * to the byte just after those absorbed by this function. Hence the
+ * caller can continue parsing from there. In the case of an error,
+ * this routine has generally positioned *s to point just to the right
+ * of the first bad spot, so that a message that has a "<--" to mark
+ * the spot will be correctly positioned.
+ * send - 1 gives a limit in *s that this function is not permitted to
+ * look beyond. That is, the function may look at bytes only in the
+ * range *s..send-1
* uv points to a UV that will hold the output value, valid only if the
* return from the function is TRUE
* error_msg is a pointer that will be set to an internal buffer giving an
return FALSE;
}
- e = strchr(*s, '}');
+ e = (char *) memchr(*s, '}', send - *s);
if (!e) {
(*s)++; /* Move past the '{' */
while (isOCTAL(**s)) { /* Position beyond the legal digits */
}
bool
-Perl_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg,
+Perl_grok_bslash_x(pTHX_ char **s, const char * const send, UV *uv,
+ const char** error_msg,
const bool output_warning, const bool strict,
const bool silence_non_portable,
const bool UTF)
* utf8 bytes, would fit within the skipped "\x{...}" bytes.
*
* On input:
- * s is the address of a pointer to a NULL terminated string that begins
- * with 'x', and the previous character was a backslash. At exit, *s
- * will be advanced to the byte just after those absorbed by this
- * function. Hence the caller can continue parsing from there. In
- * the case of an error, this routine has generally positioned *s to
- * point just to the right of the first bad spot, so that a message
- * that has a "<--" to mark the spot will be correctly positioned.
+ * s is the address of a pointer to a string. **s is 'x', and the
+ * previous character was a backslash. At exit, *s will be advanced
+ * to the byte just after those absorbed by this function. Hence the
+ * caller can continue parsing from there. In the case of an error,
+ * this routine has generally positioned *s to point just to the right
+ * of the first bad spot, so that a message that has a "<--" to mark
+ * the spot will be correctly positioned.
+ * send - 1 gives a limit in *s that this function is not permitted to
+ * look beyond. That is, the function may look at bytes only in the
+ * range *s..send-1
* uv points to a UV that will hold the output value, valid only if the
* return from the function is TRUE
* error_msg is a pointer that will be set to an internal buffer giving an
return TRUE;
}
- e = strchr(*s, '}');
+ e = (char *) memchr(*s, '}', send - *s);
if (!e) {
(*s)++; /* Move past the '{' */
while (isXDIGIT(**s)) { /* Position beyond the legal digits */
ApdR |I32 |looks_like_number|NN SV *const sv
Apd |UV |grok_bin |NN const char* start|NN STRLEN* len_p|NN I32* flags|NULLOK NV *result
#if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_TOKE_C) || defined(PERL_IN_DQUOTE_C)
-EMpRX |bool |grok_bslash_x |NN char** s|NN UV* uv \
+EMpRX |bool |grok_bslash_x |NN char** s \
+ |NN const char* const send \
+ |NN UV* uv \
|NN const char** error_msg \
|const bool output_warning \
|const bool strict \
|const bool silence_non_portable \
|const bool utf8
EMpRX |char |grok_bslash_c |const char source|const bool output_warning
-EMpRX |bool |grok_bslash_o |NN char** s|NN UV* uv \
+EMpRX |bool |grok_bslash_o |NN char** s \
+ |NN const char* const send \
+ |NN UV* uv \
|NN const char** error_msg \
|const bool output_warning \
|const bool strict \
# if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_TOKE_C) || defined(PERL_IN_DQUOTE_C)
#define form_short_octal_warning(a,b) S_form_short_octal_warning(aTHX_ a,b)
#define grok_bslash_c(a,b) Perl_grok_bslash_c(aTHX_ a,b)
-#define grok_bslash_o(a,b,c,d,e,f,g) Perl_grok_bslash_o(aTHX_ a,b,c,d,e,f,g)
-#define grok_bslash_x(a,b,c,d,e,f,g) Perl_grok_bslash_x(aTHX_ a,b,c,d,e,f,g)
+#define grok_bslash_o(a,b,c,d,e,f,g,h) Perl_grok_bslash_o(aTHX_ a,b,c,d,e,f,g,h)
+#define grok_bslash_x(a,b,c,d,e,f,g,h) Perl_grok_bslash_x(aTHX_ a,b,c,d,e,f,g,h)
#define regcurly S_regcurly
# endif
# if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_UTF8_C)
PERL_CALLCONV char Perl_grok_bslash_c(pTHX_ const char source, const bool output_warning)
__attribute__warn_unused_result__;
-PERL_CALLCONV bool Perl_grok_bslash_o(pTHX_ char** s, UV* uv, const char** error_msg, const bool output_warning, const bool strict, const bool silence_non_portable, const bool utf8)
+PERL_CALLCONV bool Perl_grok_bslash_o(pTHX_ char** s, const char* const send, UV* uv, const char** error_msg, const bool output_warning, const bool strict, const bool silence_non_portable, const bool utf8)
__attribute__warn_unused_result__;
#define PERL_ARGS_ASSERT_GROK_BSLASH_O \
- assert(s); assert(uv); assert(error_msg)
+ assert(s); assert(send); assert(uv); assert(error_msg)
-PERL_CALLCONV bool Perl_grok_bslash_x(pTHX_ char** s, UV* uv, const char** error_msg, const bool output_warning, const bool strict, const bool silence_non_portable, const bool utf8)
+PERL_CALLCONV bool Perl_grok_bslash_x(pTHX_ char** s, const char* const send, UV* uv, const char** error_msg, const bool output_warning, const bool strict, const bool silence_non_portable, const bool utf8)
__attribute__warn_unused_result__;
#define PERL_ARGS_ASSERT_GROK_BSLASH_X \
- assert(s); assert(uv); assert(error_msg)
+ assert(s); assert(send); assert(uv); assert(error_msg)
#ifndef PERL_NO_INLINE_FUNCTIONS
PERL_STATIC_INLINE I32 S_regcurly(const char *s)
const char* error_msg;
bool valid = grok_bslash_o(&p,
+ RExC_end,
&result,
&error_msg,
PASS2, /* out warnings */
const char* error_msg;
bool valid = grok_bslash_x(&p,
+ RExC_end,
&result,
&error_msg,
PASS2, /* out warnings */
{
const char* error_msg;
bool valid = grok_bslash_o(&RExC_parse,
+ RExC_end,
&value,
&error_msg,
PASS2, /* warnings only in
{
const char* error_msg;
bool valid = grok_bslash_x(&RExC_parse,
+ RExC_end,
&value,
&error_msg,
PASS2, /* Output warnings */
{
const char* error;
- bool valid = grok_bslash_o(&s, &uv, &error,
+ bool valid = grok_bslash_o(&s, PL_bufend,
+ &uv, &error,
TRUE, /* Output warning */
FALSE, /* Not strict */
TRUE, /* Output warnings for
{
const char* error;
- bool valid = grok_bslash_x(&s, &uv, &error,
+ bool valid = grok_bslash_x(&s, PL_bufend,
+ &uv, &error,
TRUE, /* Output warning */
FALSE, /* Not strict */
TRUE, /* Output warnings for