From 229dc3a47e0858a0b6772fa878a60f09ee5293 Mon Sep 17 00:00:00 2001 From: ylavic Date: Tue May 24 08:55:16 2022 Subject: [PATCH] core:make ap_escape_quotes work correctly Conflict:NA Reference:https://github.com/apache/httpd/commit/229dc3ac47e0858a0b67227fa878a60f09ee5293 --- server/util.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/server/util.c b/server/util.c index 09ac0c5..1e006a3 100644 --- a/server/util.c +++ b/server/util.c @@ -2535,7 +2535,7 @@ AP_DECLARE(void) ap_content_type_tolower(char *str) */ AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring) { - int newlen = 0; + apr_size_t size, extra = 0; const char *inchr = instring; char *outchr, *outstring; @@ -2544,9 +2544,8 @@ AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring) * 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, @@ -2554,11 +2553,31 @@ AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring) */ if ((*inchr == '\\') && (inchr[1] != '\0')) { inchr++; - newlen++; } inchr++; } - outstring = apr_palloc(p, newlen + 1); + if (!extra) { + return apr_pstrdup(p, instring); + } + + /* How large will the string become, once we escaped all the quotes? + * The tricky cases are + * - an `instring` that is already longer than `ptrdiff_t` + * can hold (which is an undefined case in C, as C defines ptrdiff_t as + * a signed difference between pointers into the same array and one index + * beyond). + * - an `instring` that, including the `extra` chars we want to add, becomes + * even larger than apr_size_t can handle. + * Since thsi function was nto designed to ever return NULL for failure, we + * can only trigger a hard assertion failure. It seems more a programming + * mistake (or failure to verify the input causing this) that leads to this + * situation. + */ + ap_assert(inchr - instring > 0); + size = ((apr_size_t)(inchr - instring)) + 1; + ap_assert(size + extra > size); + + outstring = apr_palloc(p, size + extra); inchr = instring; outchr = outstring; /* -- 2.23.0