Skip to content

Commit eb8ad30

Browse files
committed
Fix quadratic slowdown under asan in timelib
This is a hotfix for derickr/timelib#94 until the issue is resolved upstream.
1 parent c4d508c commit eb8ad30

File tree

1 file changed

+35
-24
lines changed

1 file changed

+35
-24
lines changed

ext/date/lib/parse_date.c

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -333,44 +333,55 @@ uchar *fill(Scanner *s, uchar *cursor){
333333
}
334334
#endif
335335

336+
static timelib_error_message *alloc_error_message(timelib_error_message **messages, int *count)
337+
{
338+
/* Realloc in power of two increments */
339+
int is_pow2 = (*count & (*count - 1)) == 0;
340+
if (is_pow2) {
341+
size_t alloc_size = *count ? *count * 2 : 1;
342+
*messages = timelib_realloc(*messages, alloc_size * sizeof(timelib_error_message));
343+
}
344+
return *messages + (*count)++;
345+
}
346+
336347
static void add_warning(Scanner *s, int error_code, char *error)
337348
{
338-
s->errors->warning_count++;
339-
s->errors->warning_messages = timelib_realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
340-
s->errors->warning_messages[s->errors->warning_count - 1].error_code = error_code;
341-
s->errors->warning_messages[s->errors->warning_count - 1].position = s->tok ? s->tok - s->str : 0;
342-
s->errors->warning_messages[s->errors->warning_count - 1].character = s->tok ? *s->tok : 0;
343-
s->errors->warning_messages[s->errors->warning_count - 1].message = timelib_strdup(error);
349+
timelib_error_message *message =
350+
alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count);
351+
message->error_code = error_code;
352+
message->position = s->tok ? s->tok - s->str : 0;
353+
message->character = s->tok ? *s->tok : 0;
354+
message->message = timelib_strdup(error);
344355
}
345356

346357
static void add_error(Scanner *s, int error_code, char *error)
347358
{
348-
s->errors->error_count++;
349-
s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
350-
s->errors->error_messages[s->errors->error_count - 1].error_code = error_code;
351-
s->errors->error_messages[s->errors->error_count - 1].position = s->tok ? s->tok - s->str : 0;
352-
s->errors->error_messages[s->errors->error_count - 1].character = s->tok ? *s->tok : 0;
353-
s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error);
359+
timelib_error_message *message =
360+
alloc_error_message(&s->errors->error_messages, &s->errors->error_count);
361+
message->error_code = error_code;
362+
message->position = s->tok ? s->tok - s->str : 0;
363+
message->character = s->tok ? *s->tok : 0;
364+
message->message = timelib_strdup(error);
354365
}
355366

356367
static void add_pbf_warning(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr)
357368
{
358-
s->errors->warning_count++;
359-
s->errors->warning_messages = timelib_realloc(s->errors->warning_messages, s->errors->warning_count * sizeof(timelib_error_message));
360-
s->errors->warning_messages[s->errors->warning_count - 1].error_code = error_code;
361-
s->errors->warning_messages[s->errors->warning_count - 1].position = cptr - sptr;
362-
s->errors->warning_messages[s->errors->warning_count - 1].character = *cptr;
363-
s->errors->warning_messages[s->errors->warning_count - 1].message = timelib_strdup(error);
369+
timelib_error_message *message =
370+
alloc_error_message(&s->errors->warning_messages, &s->errors->warning_count);
371+
message->error_code = error_code;
372+
message->position = cptr - sptr;
373+
message->character = *cptr;
374+
message->message = timelib_strdup(error);
364375
}
365376

366377
static void add_pbf_error(Scanner *s, int error_code, char *error, const char *sptr, const char *cptr)
367378
{
368-
s->errors->error_count++;
369-
s->errors->error_messages = timelib_realloc(s->errors->error_messages, s->errors->error_count * sizeof(timelib_error_message));
370-
s->errors->error_messages[s->errors->error_count - 1].error_code = error_code;
371-
s->errors->error_messages[s->errors->error_count - 1].position = cptr - sptr;
372-
s->errors->error_messages[s->errors->error_count - 1].character = *cptr;
373-
s->errors->error_messages[s->errors->error_count - 1].message = timelib_strdup(error);
379+
timelib_error_message *message =
380+
alloc_error_message(&s->errors->error_messages, &s->errors->error_count);
381+
message->error_code = error_code;
382+
message->position = cptr - sptr;
383+
message->character = *cptr;
384+
message->message = timelib_strdup(error);
374385
}
375386

376387
static timelib_sll timelib_meridian(const char **ptr, timelib_sll h)

0 commit comments

Comments
 (0)