1919
2020#if U_HAVE_RBNF
2121
22+ #include < limits>
2223#include " unicode/localpointer.h"
2324#include " unicode/rbnf.h"
2425#include " unicode/tblcoll.h"
@@ -116,9 +117,9 @@ NFRule::makeRules(UnicodeString& description,
116117 // new it up and initialize its basevalue and divisor
117118 // (this also strips the rule descriptor, if any, off the
118119 // description string)
119- NFRule* rule1 = new NFRule (rbnf, description, status);
120+ LocalPointer< NFRule> rule1 ( new NFRule (rbnf, description, status) );
120121 /* test for nullptr */
121- if (rule1 == nullptr ) {
122+ if (rule1. isNull () ) {
122123 status = U_MEMORY_ALLOCATION_ERROR;
123124 return ;
124125 }
@@ -144,7 +145,7 @@ NFRule::makeRules(UnicodeString& description,
144145 else {
145146 // if the description does contain a matched pair of brackets,
146147 // then it's really shorthand for two rules (with one exception)
147- NFRule* rule2 = nullptr ;
148+ LocalPointer< NFRule> rule2;
148149 UnicodeString sbuf;
149150
150151 // we'll actually only split the rule into two rules if its
@@ -160,9 +161,9 @@ NFRule::makeRules(UnicodeString& description,
160161 // set, they both have the same base value; otherwise,
161162 // increment the original rule's base value ("rule1" actually
162163 // goes SECOND in the rule set's rule list)
163- rule2 = new NFRule (rbnf, UnicodeString (), status);
164+ rule2. adoptInstead ( new NFRule (rbnf, UnicodeString (), status) );
164165 /* test for nullptr */
165- if (rule2 == nullptr ) {
166+ if (rule2. isNull () ) {
166167 status = U_MEMORY_ALLOCATION_ERROR;
167168 return ;
168169 }
@@ -217,20 +218,20 @@ NFRule::makeRules(UnicodeString& description,
217218 // BEFORE rule1 in the list: in all cases, rule2 OMITS the
218219 // material in the brackets and rule1 INCLUDES the material
219220 // in the brackets)
220- if (rule2 != nullptr ) {
221+ if (!rule2. isNull () ) {
221222 if (rule2->baseValue >= kNoBase ) {
222- rules.add (rule2);
223+ rules.add (rule2. orphan () );
223224 }
224225 else {
225- owner->setNonNumericalRule (rule2);
226+ owner->setNonNumericalRule (rule2. orphan () );
226227 }
227228 }
228229 }
229230 if (rule1->baseValue >= kNoBase ) {
230- rules.add (rule1);
231+ rules.add (rule1. orphan () );
231232 }
232233 else {
233- owner->setNonNumericalRule (rule1);
234+ owner->setNonNumericalRule (rule1. orphan () );
234235 }
235236}
236237
@@ -289,7 +290,14 @@ NFRule::parseRuleDescriptor(UnicodeString& description, UErrorCode& status)
289290 while (p < descriptorLength) {
290291 c = descriptor.charAt (p);
291292 if (c >= gZero && c <= gNine ) {
292- val = val * ll_10 + static_cast <int32_t >(c - gZero );
293+ int32_t single_digit = static_cast <int32_t >(c - gZero );
294+ if ((val > 0 && val > (std::numeric_limits<int64_t >::max () - single_digit) / 10 ) ||
295+ (val < 0 && val < (std::numeric_limits<int64_t >::min () - single_digit) / 10 )) {
296+ // out of int64_t range
297+ status = U_PARSE_ERROR;
298+ return ;
299+ }
300+ val = val * ll_10 + single_digit;
293301 }
294302 else if (c == gSlash || c == gGreaterThan ) {
295303 break ;
0 commit comments