Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/onigmo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ if(ONIGMO_CTESTS)
add_executable(test_enc_utf8 test_enc_utf8.c)
add_test(NAME test_enc_utf8 COMMAND test_enc_utf8)
target_link_libraries(test_enc_utf8 onigmo-static)

add_executable(test_repeat_id_overflow test_repeat_id_overflow.c)
Comment thread
cosmo0920 marked this conversation as resolved.
Resolved
add_test(NAME test_repeat_id_overflow COMMAND test_repeat_id_overflow)
target_link_libraries(test_repeat_id_overflow onigmo-static)
endif()

if(ONIGMO_CTESTS_SAMPLE)
Expand Down
2 changes: 2 additions & 0 deletions lib/onigmo/onigmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,8 @@ ONIG_EXTERN const OnigSyntaxType* OnigDefaultSyntax;
#define ONIGERR_NEVER_ENDING_RECURSION -221
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223
#define ONIGERR_TOO_MANY_RANGE_REPEAT -224
#define ONIGERR_TOO_MANY_NULL_CHECK -225
#define ONIGERR_INVALID_CODE_POINT_VALUE -400
#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401
Expand Down
2 changes: 2 additions & 0 deletions lib/onigmo/regcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ compile_tree_empty_check(Node* node, regex_t* reg, int empty_info)
r = add_mem_num(reg, reg->num_null_check); /* NULL CHECK ID */
if (r) return r;
reg->num_null_check++;
if ((MemNumType)reg->num_null_check <= 0) return ONIGERR_TOO_MANY_NULL_CHECK;
Comment thread
cosmo0920 marked this conversation as resolved.
Resolved
}

r = compile_tree(node, reg);
Expand Down Expand Up @@ -686,6 +687,7 @@ compile_range_repeat_node(QtfrNode* qn, int target_len, int empty_info,
if (r) return r;
r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */
reg->num_repeat++;
if ((MemNumType)reg->num_repeat <= 0) return ONIGERR_TOO_MANY_RANGE_REPEAT;
if (r) return r;
r = add_rel_addr(reg, target_len + SIZE_OP_REPEAT_INC);
if (r) return r;
Expand Down
4 changes: 4 additions & 0 deletions lib/onigmo/regerror.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ onig_error_code_to_format(OnigPosition code)
case ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY:
p = "group number is too big for capture history"; break;
#endif
case ONIGERR_TOO_MANY_RANGE_REPEAT:
p = "too many range repeat"; break;
case ONIGERR_TOO_MANY_NULL_CHECK:
p = "too many null check"; break;
case ONIGERR_INVALID_CHAR_PROPERTY_NAME:
p = "invalid character property name {%n}"; break;
case ONIGERR_TOO_MANY_CAPTURE_GROUPS:
Expand Down
47 changes: 47 additions & 0 deletions lib/onigmo/test_repeat_id_overflow.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "onigmo.h"

static int
check_pattern(const char* piece, size_t count, int expected)
{
size_t piece_len = strlen(piece);
size_t len = piece_len * count;
UChar* pattern = (UChar* )malloc(len + 1);
regex_t* reg = NULL;
OnigErrorInfo error_info;
int result;
size_t i;

if (pattern == NULL) return 1;
for (i = 0; i < count; i++)
memcpy(pattern + i * piece_len, piece, piece_len);
pattern[len] = '\0';

result = onig_new(&reg, pattern, pattern + len, ONIG_OPTION_DEFAULT,
ONIG_ENCODING_UTF8, ONIG_SYNTAX_RUBY, &error_info);
if (result != expected)
fprintf(stderr, "count=%zu: expected %d, got %d\n", count, expected, result);

if (reg != NULL) onig_free(reg);
free(pattern);
return result != expected;
}

int
main(void)
{
int failed;

if (onig_init() != ONIG_NORMAL) return 1;
failed = check_pattern("(?:fo){0,100}", 32767, ONIG_NORMAL);
failed |= check_pattern("(?:fo){0,100}", 32768,
ONIGERR_TOO_MANY_RANGE_REPEAT);
failed |= check_pattern("(?:fo){0,100}", 32769,
ONIGERR_TOO_MANY_RANGE_REPEAT);
failed |= check_pattern("(?:a|)*", 40000,
ONIGERR_TOO_MANY_NULL_CHECK);
onig_end();
return failed;
}
Loading