Fix an early fail optimization issue and a buffer overread in JIT.

This commit is contained in:
Zoltán Herczeg 2020-07-15 04:35:32 +00:00
parent 0ad89ab06d
commit 3d317692ac
3 changed files with 17 additions and 12 deletions

View File

@ -48,6 +48,10 @@ generates *.pc files and pcre2-config with the same content, as in the past.
single digit, the code unit beyond d was being read (i.e. there was a read single digit, the code unit beyond d was being read (i.e. there was a read
buffer overflow). Fixes ClusterFuzz 23779. buffer overflow). Fixes ClusterFuzz 23779.
9. After the rework in r1235, certain character ranges were incorrectly
handled by an optimization in JIT. Furthermore a wrong offset was used to
read a value from a buffer which could lead to memory overread.
Version 10.35 09-May-2020 Version 10.35 09-May-2020
--------------------------- ---------------------------

View File

@ -1466,9 +1466,9 @@ do
default: default:
accelerated_start = NULL; accelerated_start = NULL;
fast_forward_allowed = FALSE; fast_forward_allowed = FALSE;
break;
}
continue; continue;
}
break;
case OP_ONCE: case OP_ONCE:
case OP_BRA: case OP_BRA:
@ -1834,57 +1834,57 @@ while (cc < ccend)
case OP_BRAZERO: case OP_BRAZERO:
case OP_BRAMINZERO: case OP_BRAMINZERO:
case OP_BRAPOSZERO: case OP_BRAPOSZERO:
repeat_check = FALSE;
size = 1; size = 1;
repeat_check = FALSE;
break; break;
CASE_ITERATOR_PRIVATE_DATA_1 CASE_ITERATOR_PRIVATE_DATA_1
space = 1;
size = -2; size = -2;
space = 1;
break; break;
CASE_ITERATOR_PRIVATE_DATA_2A CASE_ITERATOR_PRIVATE_DATA_2A
space = 2;
size = -2; size = -2;
space = 2;
break; break;
CASE_ITERATOR_PRIVATE_DATA_2B CASE_ITERATOR_PRIVATE_DATA_2B
space = 2;
size = -(2 + IMM2_SIZE); size = -(2 + IMM2_SIZE);
space = 2;
break; break;
CASE_ITERATOR_TYPE_PRIVATE_DATA_1 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
space = 1;
size = 1; size = 1;
space = 1;
break; break;
CASE_ITERATOR_TYPE_PRIVATE_DATA_2A CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
size = 1;
if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
space = 2; space = 2;
size = 1;
break; break;
case OP_TYPEUPTO: case OP_TYPEUPTO:
size = 1 + IMM2_SIZE;
if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
space = 2; space = 2;
size = 1 + IMM2_SIZE;
break; break;
case OP_TYPEMINUPTO: case OP_TYPEMINUPTO:
space = 2;
size = 1 + IMM2_SIZE; size = 1 + IMM2_SIZE;
space = 2;
break; break;
case OP_CLASS: case OP_CLASS:
case OP_NCLASS: case OP_NCLASS:
space = get_class_iterator_size(cc + size);
size = 1 + 32 / sizeof(PCRE2_UCHAR); size = 1 + 32 / sizeof(PCRE2_UCHAR);
space = get_class_iterator_size(cc + size);
break; break;
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
case OP_XCLASS: case OP_XCLASS:
space = get_class_iterator_size(cc + size);
size = GET(cc, 1); size = GET(cc, 1);
space = get_class_iterator_size(cc + size);
break; break;
#endif #endif

View File

@ -350,6 +350,7 @@ static struct regression_test_case regression_test_cases[] = {
{ MU, A, 0, 0, ".[ab]*.", "xx" }, { MU, A, 0, 0, ".[ab]*.", "xx" },
{ MU, A, 0, 0, ".[ab]*a", "xxa" }, { MU, A, 0, 0, ".[ab]*a", "xxa" },
{ MU, A, 0, 0, ".[ab]?.", "xx" }, { MU, A, 0, 0, ".[ab]?.", "xx" },
{ MU, A, 0, 0, "_[ab]+_*a", "_aa" },
/* Bracket repeats with limit. */ /* Bracket repeats with limit. */
{ MU, A, 0, 0, "(?:(ab){2}){5}M", "abababababababababababM" }, { MU, A, 0, 0, "(?:(ab){2}){5}M", "abababababababababababM" },