diff options
author | Matthew Vernon <matthew@debian.org> | 2017-03-21 22:31:45 +0000 |
---|---|---|
committer | Matthew Vernon <matthew@debian.org> | 2017-03-21 22:31:45 +0000 |
commit | 8a44b106f405e278f4fbbcd1e8b2744cd9afbc57 (patch) | |
tree | 67b78aa23cc717ba1a1a6d47ea7d45fc76c8993a | |
parent | 487b38705d229d0bf07f402b8ed5a4c4471b768b (diff) |
CVE-2017-7186 fix (upstream rev 670)
Fix 32-bit non-UTF property test crash.
-rw-r--r-- | src/pcre2_internal.h | 15 | ||||
-rw-r--r-- | src/pcre2_ucd.c | 14 | ||||
-rw-r--r-- | testdata/testinput12 | 3 | ||||
-rw-r--r-- | testdata/testoutput12-16 | 6 | ||||
-rw-r--r-- | testdata/testoutput12-32 | 4 |
5 files changed, 41 insertions, 1 deletions
diff --git a/src/pcre2_internal.h b/src/pcre2_internal.h index 5690870..7fb374d 100644 --- a/src/pcre2_internal.h +++ b/src/pcre2_internal.h @@ -1794,10 +1794,17 @@ typedef struct { /* UCD access macros */ #define UCD_BLOCK_SIZE 128 -#define GET_UCD(ch) (PRIV(ucd_records) + \ +#define REAL_GET_UCD(ch) (PRIV(ucd_records) + \ PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \ UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE]) +#if PCRE2_CODE_UNIT_WIDTH == 32 +#define GET_UCD(ch) ((ch > MAX_UTF_CODE_POINT)? \ + PRIV(dummy_ucd_record) : REAL_GET_UCD(ch)) +#else +#define GET_UCD(ch) REAL_GET_UCD(ch) +#endif + #define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype #define UCD_SCRIPT(ch) GET_UCD(ch)->script #define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] @@ -1854,6 +1861,9 @@ extern const uint8_t PRIV(utf8_table4)[]; #define _pcre2_default_compile_context PCRE2_SUFFIX(_pcre2_default_compile_context_) #define _pcre2_default_match_context PCRE2_SUFFIX(_pcre2_default_match_context_) #define _pcre2_default_tables PCRE2_SUFFIX(_pcre2_default_tables_) +#if PCRE2_CODE_UNIT_WIDTH == 32 +#define _pcre2_dummy_ucd_record PCRE2_SUFFIX(_pcre2_dummy_ucd_record_) +#endif #define _pcre2_hspace_list PCRE2_SUFFIX(_pcre2_hspace_list_) #define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_) #define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_) @@ -1878,6 +1888,9 @@ extern const uint32_t PRIV(hspace_list)[]; extern const uint32_t PRIV(vspace_list)[]; extern const uint32_t PRIV(ucd_caseless_sets)[]; extern const ucd_record PRIV(ucd_records)[]; +#if PCRE2_CODE_UNIT_WIDTH == 32 +extern const ucd_record PRIV(dummy_ucd_record)[]; +#endif extern const uint8_t PRIV(ucd_stage1)[]; extern const uint16_t PRIV(ucd_stage2)[]; extern const uint32_t PRIV(ucp_gbtable)[]; diff --git a/src/pcre2_ucd.c b/src/pcre2_ucd.c index 116f537..56aa29d 100644 --- a/src/pcre2_ucd.c +++ b/src/pcre2_ucd.c @@ -41,6 +41,20 @@ const uint32_t PRIV(ucd_caseless_sets)[] = {0}; const char *PRIV(unicode_version) = "8.0.0"; +/* If the 32-bit library is run in non-32-bit mode, character values +greater than 0x10ffff may be encountered. For these we set up a +special record. */ + +#if PCRE2_CODE_UNIT_WIDTH == 32 +const ucd_record PRIV(dummy_ucd_record)[] = {{ + ucp_Common, /* script */ + ucp_Cn, /* type unassigned */ + ucp_gbOther, /* grapheme break property */ + 0, /* case set */ + 0, /* other case */ + }}; +#endif + /* When recompiling tables with a new Unicode version, please check the types in this structure definition from pcre2_internal.h (the actual field names will be different): diff --git a/testdata/testinput12 b/testdata/testinput12 index 14a7715..86f2c74 100644 --- a/testdata/testinput12 +++ b/testdata/testinput12 @@ -343,4 +343,7 @@ /./utf \x{110000} +/\pP/ucp + \x{7fffffff}\=no_jit + # End of testinput12 diff --git a/testdata/testoutput12-16 b/testdata/testoutput12-16 index 383a032..b19f6c4 100644 --- a/testdata/testoutput12-16 +++ b/testdata/testoutput12-16 @@ -1367,4 +1367,10 @@ Subject length lower bound = 2 \x{110000} ** Failed: character \x{110000} is greater than 0x10ffff and so cannot be converted to UTF-16 +/\pP/ucp + \x{7fffffff}\=no_jit +** Character \x{7fffffff} is greater than 0xffff and UTF-16 mode is not enabled. +** Truncation will probably give the wrong result. +No match + # End of testinput12 diff --git a/testdata/testoutput12-32 b/testdata/testoutput12-32 index 95f1834..220f4f1 100644 --- a/testdata/testoutput12-32 +++ b/testdata/testoutput12-32 @@ -1361,4 +1361,8 @@ Subject length lower bound = 2 \x{110000} Failed: error -28: UTF-32 error: code points greater than 0x10ffff are not defined at offset 0 +/\pP/ucp + \x{7fffffff}\=no_jit +No match + # End of testinput12 |