summaryrefslogtreecommitdiff
path: root/dquote_static.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-03-18 11:53:23 +0000
committerDavid Mitchell <davem@iabyn.com>2015-03-18 11:58:29 +0000
commit61caa4da928ef1eca4b5e5fda1025112b3710747 (patch)
treecb5c2b3dcd94f3766a81b51bf32e7d083f6ca805 /dquote_static.c
parent7d8b9a6b60f8be7f46fd0101ca36da898fd7615f (diff)
downloadperl-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.c30
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;
}