From: Nikita Popov Date: Tue, 16 Feb 2021 10:54:34 +0000 (+0100) Subject: Fix quadratic slowdown under asan in timelib X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eb8ad30cf161dd688265da2b8ae8c4ebb5fcd549;p=php Fix quadratic slowdown under asan in timelib This is a hotfix for https://github.com/derickr/timelib/pull/94 until the issue is resolved upstream. --- diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index 0444802778..857489e04d 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -333,44 +333,55 @@ uchar *fill(Scanner *s, uchar *cursor){ } #endif +static timelib_error_message *alloc_error_message(timelib_error_message **messages, int *count) +{ + /* Realloc in power of two increments */ + int is_pow2 = (*count & (*count - 1)) == 0; + if (is_pow2) { + size_t alloc_size = *count ? *count * 2 : 1; + *messages = timelib_realloc(*messages, alloc_size * sizeof(timelib_error_message)); + } + return *messages + (*count)++; +} + static void add_warning(Scanner *s, int error_code, char *error) { - s->errors->warning_count++; - s->errors->warning_messages = timelib_realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message)); - s->errors->warning_messages[s->errors->warning_count - 1].error_code = error_code; - s->errors->warning_messages[s->errors->warning_count - 1].position = s->tok ? s->tok - s->str : 0; - s->errors->warning_messages[s->errors->warning_count - 1].character = s->tok ? *s->tok : 0; - s->errors->warning_messages[s->errors->warning_count - 1].message = timelib_strdup(error); + timelib_error_message *message = + alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count); + message->error_code = error_code; + message->position = s->tok ? s->tok - s->str : 0; + message->character = s->tok ? *s->tok : 0; + message->message = timelib_strdup(error); } static void add_error(Scanner *s, int error_code, char *error) { - s->errors->error_count++; - s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message)); - s->errors->error_messages[s->errors->error_count - 1].error_code = error_code; - s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0; - s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0; - s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error); + timelib_error_message *message = + alloc_error_message(&s->errors->error_messages, &s->errors->error_count); + message->error_code = error_code; + message->position = s->tok ? s->tok - s->str : 0; + message->character = s->tok ? *s->tok : 0; + message->message = timelib_strdup(error); } static void add_pbf_warning(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr) { - s->errors->warning_count++; - s->errors->warning_messages = timelib_realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message)); - s->errors->warning_messages[s->errors->warning_count - 1].error_code = error_code; - s->errors->warning_messages[s->errors->warning_count - 1].position = cptr - sptr; - s->errors->warning_messages[s->errors->warning_count - 1].character = *cptr; - s->errors->warning_messages[s->errors->warning_count - 1].message = timelib_strdup(error); + timelib_error_message *message = + alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count); + message->error_code = error_code; + message->position = cptr - sptr; + message->character = *cptr; + message->message = timelib_strdup(error); } static void add_pbf_error(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr) { - s->errors->error_count++; - s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message)); - s->errors->error_messages[s->errors->error_count - 1].error_code = error_code; - s->errors->error_messages[s->errors->error_count - 1].position = cptr - sptr; - s->errors->error_messages[s->errors->error_count - 1].character = *cptr; - s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error); + timelib_error_message *message = + alloc_error_message(&s->errors->error_messages, &s->errors->error_count); + message->error_code = error_code; + message->position = cptr - sptr; + message->character = *cptr; + message->message = timelib_strdup(error); } static timelib_sll timelib_meridian(const char **ptr, timelib_sll h)