|
| 1 | +From 0b0011c3ef49c8c6c2c902d5ae5dda5656cb9162 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Frank Tang < [email protected]> |
| 3 | +Date: Wed, 22 Jan 2025 11:50:59 -0800 |
| 4 | +Subject: [PATCH] ICU-22973 Fix buffer overflow by using CharString |
| 5 | + |
| 6 | +Signed-off-by: Azure Linux Security Servicing Account < [email protected]> |
| 7 | +Upstream-reference: https://github.com/unicode-org/icu/commit/2c667e31cfd0b6bb1923627a932fd3453a5bac77.patch |
| 8 | +--- |
| 9 | + icu/icu4c/source/tools/genrb/parse.cpp | 49 +++++++++++++++----------- |
| 10 | + 1 file changed, 29 insertions(+), 20 deletions(-) |
| 11 | + |
| 12 | +diff --git a/icu/icu4c/source/tools/genrb/parse.cpp b/icu/icu4c/source/tools/genrb/parse.cpp |
| 13 | +index 96fd81a..b590a03 100644 |
| 14 | +--- a/icu/icu4c/source/tools/genrb/parse.cpp |
| 15 | ++++ b/icu/icu4c/source/tools/genrb/parse.cpp |
| 16 | +@@ -1153,7 +1153,7 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp |
| 17 | + struct UString *tokenValue; |
| 18 | + struct UString comment; |
| 19 | + enum ETokenType token; |
| 20 | +- char subtag[1024]; |
| 21 | ++ CharString subtag; |
| 22 | + UnicodeString rules; |
| 23 | + UBool haveRules = false; |
| 24 | + UVersionInfo version; |
| 25 | +@@ -1189,15 +1189,15 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp |
| 26 | + return NULL; |
| 27 | + } |
| 28 | + |
| 29 | +- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); |
| 30 | +- |
| 31 | ++ subtag.clear(); |
| 32 | ++ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); |
| 33 | + if (U_FAILURE(*status)) |
| 34 | + { |
| 35 | + res_close(result); |
| 36 | + return NULL; |
| 37 | + } |
| 38 | + |
| 39 | +- member = parseResource(state, subtag, NULL, status); |
| 40 | ++ member = parseResource(state, subtag.data(), NULL, status); |
| 41 | + |
| 42 | + if (U_FAILURE(*status)) |
| 43 | + { |
| 44 | +@@ -1208,7 +1208,7 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp |
| 45 | + { |
| 46 | + // Ignore the parsed resources, continue parsing. |
| 47 | + } |
| 48 | +- else if (uprv_strcmp(subtag, "Version") == 0 && member->isString()) |
| 49 | ++ else if (uprv_strcmp(subtag.data(), "Version") == 0 && member->isString()) |
| 50 | + { |
| 51 | + StringResource *sr = static_cast<StringResource *>(member); |
| 52 | + char ver[40]; |
| 53 | +@@ -1225,11 +1225,11 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp |
| 54 | + result->add(member, line, *status); |
| 55 | + member = NULL; |
| 56 | + } |
| 57 | +- else if(uprv_strcmp(subtag, "%%CollationBin")==0) |
| 58 | ++ else if(uprv_strcmp(subtag.data(), "%%CollationBin")==0) |
| 59 | + { |
| 60 | + /* discard duplicate %%CollationBin if any*/ |
| 61 | + } |
| 62 | +- else if (uprv_strcmp(subtag, "Sequence") == 0 && member->isString()) |
| 63 | ++ else if (uprv_strcmp(subtag.data(), "Sequence") == 0 && member->isString()) |
| 64 | + { |
| 65 | + StringResource *sr = static_cast<StringResource *>(member); |
| 66 | + rules = sr->fString; |
| 67 | +@@ -1395,7 +1395,7 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n |
| 68 | + struct UString *tokenValue; |
| 69 | + struct UString comment; |
| 70 | + enum ETokenType token; |
| 71 | +- char subtag[1024], typeKeyword[1024]; |
| 72 | ++ CharString subtag, typeKeyword; |
| 73 | + uint32_t line; |
| 74 | + |
| 75 | + result = table_open(state->bundle, tag, NULL, status); |
| 76 | +@@ -1437,7 +1437,8 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n |
| 77 | + return NULL; |
| 78 | + } |
| 79 | + |
| 80 | +- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); |
| 81 | ++ subtag.clear(); |
| 82 | ++ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); |
| 83 | + |
| 84 | + if (U_FAILURE(*status)) |
| 85 | + { |
| 86 | +@@ -1445,9 +1446,9 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n |
| 87 | + return NULL; |
| 88 | + } |
| 89 | + |
| 90 | +- if (uprv_strcmp(subtag, "default") == 0) |
| 91 | ++ if (uprv_strcmp(subtag.data(), "default") == 0) |
| 92 | + { |
| 93 | +- member = parseResource(state, subtag, NULL, status); |
| 94 | ++ member = parseResource(state, subtag.data(), NULL, status); |
| 95 | + |
| 96 | + if (U_FAILURE(*status)) |
| 97 | + { |
| 98 | +@@ -1466,22 +1467,29 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n |
| 99 | + if(token == TOK_OPEN_BRACE) { |
| 100 | + token = getToken(state, &tokenValue, &comment, &line, status); |
| 101 | + TableResource *collationRes; |
| 102 | +- if (keepCollationType(subtag)) { |
| 103 | +- collationRes = table_open(state->bundle, subtag, NULL, status); |
| 104 | ++ if (keepCollationType(subtag.data())) { |
| 105 | ++ collationRes = table_open(state->bundle, subtag.data(), NULL, status); |
| 106 | + } else { |
| 107 | + collationRes = NULL; |
| 108 | + } |
| 109 | + // need to parse the collation data regardless |
| 110 | +- collationRes = addCollation(state, collationRes, subtag, startline, status); |
| 111 | ++ collationRes = addCollation(state, collationRes, subtag.data(), startline, status); |
| 112 | + if (collationRes != NULL) { |
| 113 | + result->add(collationRes, startline, *status); |
| 114 | + } |
| 115 | + } else if(token == TOK_COLON) { /* right now, we'll just try to see if we have aliases */ |
| 116 | + /* we could have a table too */ |
| 117 | + token = peekToken(state, 1, &tokenValue, &line, &comment, status); |
| 118 | +- u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(tokenValue->fChars) + 1); |
| 119 | +- if(uprv_strcmp(typeKeyword, "alias") == 0) { |
| 120 | +- member = parseResource(state, subtag, NULL, status); |
| 121 | ++ typeKeyword.clear(); |
| 122 | ++ typeKeyword.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); |
| 123 | ++ if (U_FAILURE(*status)) |
| 124 | ++ { |
| 125 | ++ res_close(result); |
| 126 | ++ return NULL; |
| 127 | ++ } |
| 128 | ++ |
| 129 | ++ if(uprv_strcmp(typeKeyword.data(), "alias") == 0) { |
| 130 | ++ member = parseResource(state, subtag.data(), NULL, status); |
| 131 | + if (U_FAILURE(*status)) |
| 132 | + { |
| 133 | + res_close(result); |
| 134 | +@@ -1523,7 +1531,7 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star |
| 135 | + struct UString *tokenValue=NULL; |
| 136 | + struct UString comment; |
| 137 | + enum ETokenType token; |
| 138 | +- char subtag[1024]; |
| 139 | ++ CharString subtag; |
| 140 | + uint32_t line; |
| 141 | + UBool readToken = false; |
| 142 | + |
| 143 | +@@ -1562,7 +1570,8 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star |
| 144 | + } |
| 145 | + |
| 146 | + if(uprv_isInvariantUString(tokenValue->fChars, -1)) { |
| 147 | +- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); |
| 148 | ++ subtag.clear(); |
| 149 | ++ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); |
| 150 | + } else { |
| 151 | + *status = U_INVALID_FORMAT_ERROR; |
| 152 | + error(line, "invariant characters required for table keys"); |
| 153 | +@@ -1575,7 +1584,7 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star |
| 154 | + return NULL; |
| 155 | + } |
| 156 | + |
| 157 | +- member = parseResource(state, subtag, &comment, status); |
| 158 | ++ member = parseResource(state, subtag.data(), &comment, status); |
| 159 | + |
| 160 | + if (member == NULL || U_FAILURE(*status)) |
| 161 | + { |
| 162 | +-- |
| 163 | +2.45.4 |
| 164 | + |
0 commit comments