summaryrefslogtreecommitdiff
path: root/ext/date/lib/parse_date.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-02-16 11:54:34 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-02-16 11:56:17 +0100
commiteb8ad30cf161dd688265da2b8ae8c4ebb5fcd549 (patch)
tree5ba882412e9a53f6032236b98f2113f8bca541c9 /ext/date/lib/parse_date.c
parentc4d508c2bc09860bfa15b7f520e0ba68425acfc1 (diff)
downloadphp-git-eb8ad30cf161dd688265da2b8ae8c4ebb5fcd549.tar.gz
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.
Diffstat (limited to 'ext/date/lib/parse_date.c')
-rw-r--r--ext/date/lib/parse_date.c59
1 files changed, 35 insertions, 24 deletions
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)