diff options
author | David Mitchell <davem@iabyn.com> | 2015-03-18 11:53:23 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2015-03-18 11:58:29 +0000 |
commit | 61caa4da928ef1eca4b5e5fda1025112b3710747 (patch) | |
tree | cb5c2b3dcd94f3766a81b51bf32e7d083f6ca805 /dquote_static.c | |
parent | 7d8b9a6b60f8be7f46fd0101ca36da898fd7615f (diff) | |
download | perl-61caa4da928ef1eca4b5e5fda1025112b3710747.tar.gz |
S_grok_bslash_[ox]: assert char fits
S_grok_bslash_o() and S_grok_bslash_x() scan \o{...} and \x{...} in a
string, and return a UV codepoint. Some callers assume that if that
codepoint is converted into a series of utf8 bytes and re-inserted into
the string, that it will tale up less space than the original "\x{...}"
sequence. Add asserts that this is indeed so.
Diffstat (limited to 'dquote_static.c')
-rw-r--r-- | dquote_static.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/dquote_static.c b/dquote_static.c index 93c023b01e..401bf478eb 100644 --- a/dquote_static.c +++ b/dquote_static.c @@ -88,7 +88,9 @@ S_grok_bslash_o(pTHX_ char **s, UV *uv, const char** error_msg, /* Documentation to be supplied when interface nailed down finally * This returns FALSE if there is an error which the caller need not recover - * from; , otherwise TRUE. In either case the caller should look at *len + * from; otherwise TRUE. In either case the caller should look at *len [???]. + * It guarantees that the returned codepoint, *uv, when expressed as + * 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 'o', and the previous character was a backslash. At exit, *s @@ -118,6 +120,11 @@ S_grok_bslash_o(pTHX_ char **s, UV *uv, const char** error_msg, * ourselves */ | PERL_SCAN_SILENT_ILLDIGIT; +#ifdef DEBUGGING + char *start = *s - 1; + assert(*start == '\\'); +#endif + PERL_ARGS_ASSERT_GROK_BSLASH_O; @@ -176,6 +183,10 @@ S_grok_bslash_o(pTHX_ char **s, UV *uv, const char** error_msg, /* Return past the '}' */ *s = e + 1; + /* guarantee replacing "\x{...}" with utf8 bytes fits within + * existing space */ + assert(OFFUNISKIP(*uv) < *s - start); + return TRUE; } @@ -188,7 +199,10 @@ S_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg, /* Documentation to be supplied when interface nailed down finally * This returns FALSE if there is an error which the caller need not recover - * from; , otherwise TRUE. + * from; otherwise TRUE. + * It guarantees that the returned codepoint, *uv, when expressed as + * 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 @@ -215,6 +229,10 @@ S_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg, char* e; STRLEN numbers_len; I32 flags = PERL_SCAN_DISALLOW_PREFIX; +#ifdef DEBUGGING + char *start = *s - 1; + assert(*start == '\\'); +#endif PERL_ARGS_ASSERT_GROK_BSLASH_X; @@ -240,7 +258,7 @@ S_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg, } return FALSE; } - return TRUE; + goto ok; } e = strchr(*s, '}'); @@ -267,7 +285,7 @@ S_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg, } *s = e + 1; *uv = 0; - return TRUE; + goto ok; } flags |= PERL_SCAN_ALLOW_UNDERSCORES; @@ -289,6 +307,10 @@ S_grok_bslash_x(pTHX_ char **s, UV *uv, const char** error_msg, /* Return past the '}' */ *s = e + 1; + ok: + /* guarantee replacing "\x{...}" with utf8 bytes fits within + * existing space */ + assert(OFFUNISKIP(*uv) < *s - start); return TRUE; } |