with more than MAX_INT/2 characters, counting quotes double.
Credit to <generalbugs@zippenhop.com> for finding this.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@
1899609 13f79535-47bb-0310-9956-
ffa450edef68
--- /dev/null
+ *) core: make ap_escape_quotes() work correctly on strings
+ with more than MAX_INT/2 characters, counting quotes double.
+ Credit to <generalbugs@zippenhop.com> for finding this.
+ [Stefan Eissing]
\ No newline at end of file
*/
AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring)
{
- int newlen = 0;
+ apr_ssize_t extra = 0;
const char *inchr = instring;
char *outchr, *outstring;
* string up by an extra byte each time we find an unescaped ".
*/
while (*inchr != '\0') {
- newlen++;
if (*inchr == '"') {
- newlen++;
+ extra++;
}
/*
* If we find a slosh, and it's not the last byte in the string,
*/
else if ((*inchr == '\\') && (inchr[1] != '\0')) {
inchr++;
- newlen++;
}
inchr++;
}
- outstring = apr_palloc(p, newlen + 1);
+
+ if (!extra) {
+ return apr_pstrdup(p, instring);
+ }
+
+ outstring = apr_palloc(p, (inchr - instring) + extra + 1);
inchr = instring;
outchr = outstring;
/*
}
END_TEST
+
+/*
+ * ap_escape_quotes()
+ */
+
+struct ap_escape_quotes_case {
+ const char *input;
+ const char *expected;
+};
+
+#define ESCQ "\\\""
+
+const struct ap_escape_quotes_case ap_test_escape_quotes_cases[] = {
+ { "one", "one" },
+ { "o\"ne", "o"ESCQ"ne" },
+ { "o"ESCQ"ne", "o"ESCQ"ne" },
+ { "one\\", "one\\" },
+ { "o\\ne", "o\\ne" },
+ { "o\\"ESCQ"ne", "o\\\\"ESCQ"ne" }, /* 1st \ escapes 2nd, following '"' needs \ */
+};
+
+const size_t ap_test_escape_quotes_cases_len = sizeof(ap_test_escape_quotes_cases) /
+ sizeof(ap_test_escape_quotes_cases[0]);
+
+HTTPD_START_LOOP_TEST(check_escape_quotes, ap_test_escape_quotes_cases_len)
+{
+ const struct ap_escape_quotes_case *c = &ap_test_escape_quotes_cases[_i];
+ const char *result;
+
+ result = ap_escape_quotes(g_pool, c->input);
+ ck_assert_str_eq(result, c->expected);
+}
+END_TEST
+
+
/*
* Test Case Boilerplate
*/