Skip to content
Open
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
6 changes: 5 additions & 1 deletion icu4c/source/common/filteredbrk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,11 @@ SimpleFilteredBreakIteratorBuilder::build(BreakIterator* adoptBreakIterator, UEr
LocalArray<UnicodeString> ustrs(ustrs_ptr);

LocalMemory<int> partials;
partials.allocateInsteadAndReset(subCount);
// Check subCount > 0 to distinguish allocation failure from empty set (both return nullptr)
if (subCount > 0 && partials.allocateInsteadAndReset(subCount) == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return nullptr;
}

LocalPointer<UCharsTrie> backwardsTrie; // i.e. ".srM" for Mrs.
LocalPointer<UCharsTrie> forwardsPartialTrie; // Has ".a" for "a.M."
Expand Down
5 changes: 4 additions & 1 deletion icu4c/source/common/loclikelysubtags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,10 @@ LSR LikelySubtags::makeMaximizedLsrFrom(const Locale &locale,
}
LSR max = makeMaximizedLsr(locale.getLanguage(), locale.getScript(), locale.getCountry(),
locale.getVariant(), returnInputIfUnmatch, errorCode);

if (!U_SUCCESS(errorCode)) {
return LSR(name, "", "", LSR::EXPLICIT_LSR);
}

if (uprv_strlen(max.language) == 0 &&
uprv_strlen(max.script) == 0 &&
uprv_strlen(max.region) == 0) {
Expand Down
7 changes: 7 additions & 0 deletions icu4c/source/common/normalizer2impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,10 @@ Normalizer2Impl::copyLowPrefixFromNulTerminated(const char16_t *src,
// data and check the first part of the string.
// After this prefix, determine the string length to simplify the rest
// of the code.
if(src==nullptr) {
errorCode=U_ILLEGAL_ARGUMENT_ERROR;
return src;
}
const char16_t *prevSrc=src;
char16_t c;
while((c=*src++)<minNeedDataCP && c!=0) {}
Expand Down Expand Up @@ -1731,6 +1735,9 @@ Normalizer2Impl::composeQuickCheck(const char16_t *src, const char16_t *limit,
if(limit==nullptr) {
UErrorCode errorCode=U_ZERO_ERROR;
src=copyLowPrefixFromNulTerminated(src, minNoMaybeCP, nullptr, errorCode);
if (U_FAILURE(errorCode)) {
return src;
}
limit=u_strchr(src, 0);
if (prevBoundary != src) {
if (hasCompBoundaryAfter(*(src-1), onlyContiguous)) {
Expand Down
11 changes: 11 additions & 0 deletions icu4c/source/common/ubidiln.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,12 @@ ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex,
{
int32_t start;
UErrorCode errorCode = U_ZERO_ERROR;
if(pLogicalStart!=nullptr) {
*pLogicalStart=0;
}
if(pLength!=nullptr) {
*pLength=0;
}
RETURN_IF_NOT_VALID_PARA_OR_LINE(pBiDi, errorCode, UBIDI_LTR);
ubidi_getRuns(pBiDi, &errorCode);
if(U_FAILURE(errorCode)) {
Expand Down Expand Up @@ -585,6 +591,10 @@ ubidi_getRuns(UBiDi *pBiDi, UErrorCode*) {
}
}

if (runCount==0) {
return false;
}

/*
* We don't need to see if the last run can be merged with a trailing
* WS run because setTrailingWSStart() would have done that.
Expand Down Expand Up @@ -645,6 +655,7 @@ ubidi_getRuns(UBiDi *pBiDi, UErrorCode*) {
/* there is a separate WS run */
runs[runIndex].logicalStart=limit;
runs[runIndex].visualLimit=length-limit;
runs[runIndex].insertRemove=0;
/* For the trailing WS run, pBiDi->paraLevel is ok even
if contextual multiple paragraphs. */
if(pBiDi->paraLevel<minLevel) {
Expand Down
19 changes: 5 additions & 14 deletions icu4c/source/common/ubidiwrt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,12 @@ doWriteForward(const char16_t *src, int32_t srcLength,
char16_t *dest, int32_t destSize,
uint16_t options,
UErrorCode *pErrorCode) {
if (srcLength<=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
/* optimize for several combinations of options */
switch(options&(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING)) {
case 0: {
/* simply copy the LTR run to the destination */
int32_t length=srcLength;
if(destSize<length) {
if(!destSize || destSize<length) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
return srcLength;
}
Expand All @@ -83,7 +79,7 @@ doWriteForward(const char16_t *src, int32_t srcLength,
int32_t i=0, j=0;
UChar32 c;

if(destSize<srcLength) {
if(!destSize || destSize<srcLength) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
return srcLength;
}
Expand Down Expand Up @@ -178,11 +174,6 @@ doWriteReverse(const char16_t *src, int32_t srcLength,
int32_t i, j;
UChar32 c;

if(srcLength<=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}

/* optimize for several combinations of options */
switch(options&(UBIDI_REMOVE_BIDI_CONTROLS|UBIDI_DO_MIRRORING|UBIDI_KEEP_BASE_COMBINING)) {
case 0:
Expand All @@ -192,7 +183,7 @@ doWriteReverse(const char16_t *src, int32_t srcLength,
* and there is no mirroring and no keeping combining characters
* with their base characters.
*/
if(destSize<srcLength) {
if(!destSize || destSize<srcLength) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
return srcLength;
}
Expand Down Expand Up @@ -220,7 +211,7 @@ doWriteReverse(const char16_t *src, int32_t srcLength,
* and there is no mirroring.
* We do need to keep combining characters with their base characters.
*/
if(destSize<srcLength) {
if(!destSize || destSize<srcLength) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
return srcLength;
}
Expand Down Expand Up @@ -269,7 +260,7 @@ doWriteReverse(const char16_t *src, int32_t srcLength,
src-=srcLength;
}

if(destSize<i) {
if(!destSize || destSize<i) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
return i;
}
Expand Down
9 changes: 7 additions & 2 deletions icu4c/source/common/ucnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,7 @@ _fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) {
const char16_t *realSource, *realSourceLimit;
int32_t realSourceIndex;
UBool realFlush;
UBool needRestore=false;

cnv=pArgs->converter;
s=pArgs->source;
Expand Down Expand Up @@ -891,6 +892,7 @@ _fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) {
pArgs->sourceLimit=replay-cnv->preFromULength;
pArgs->flush=false;
sourceIndex=-1;
needRestore=true;

cnv->preFromULength=0;
}
Expand Down Expand Up @@ -982,6 +984,7 @@ _fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) {
if((sourceIndex+=cnv->preFromULength)<0) {
sourceIndex=-1;
}
needRestore=true;

cnv->preFromULength=0;
} else {
Expand All @@ -1002,14 +1005,15 @@ _fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) {
* (continue converting by breaking out of only the inner loop)
*/
break;
} else if(realSource!=nullptr) {
} else if(needRestore) {
/* switch back from replaying to the real source and continue */
pArgs->source=realSource;
pArgs->sourceLimit=realSourceLimit;
pArgs->flush=realFlush;
sourceIndex=realSourceIndex;

realSource=nullptr;
needRestore=false;
break;
} else if(pArgs->flush && cnv->fromUChar32!=0) {
/*
Expand Down Expand Up @@ -1065,7 +1069,7 @@ _fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) {
* copied back into the UConverter
* and the real arguments must be restored
*/
if(realSource!=nullptr) {
if(needRestore) {
int32_t length;

U_ASSERT(cnv->preFromULength==0);
Expand All @@ -1079,6 +1083,7 @@ _fromUnicodeWithCallback(UConverterFromUnicodeArgs *pArgs, UErrorCode *err) {
pArgs->source=realSource;
pArgs->sourceLimit=realSourceLimit;
pArgs->flush=realFlush;
needRestore=false;
}

return;
Expand Down
7 changes: 6 additions & 1 deletion icu4c/source/common/ucnv2022.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,18 @@ enum { MAX_JA_VERSION=0 };
#else
enum { MAX_JA_VERSION=4 };
#endif
static const uint16_t jpCharsetMasks[MAX_JA_VERSION+1]={
static const uint16_t jpCharsetMasks[5]={
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT),
#if !UCONFIG_ONLY_HTML_CONVERSION
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212),
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212)|CSM(GB2312)|CSM(KSC5601)|CSM(ISO8859_1)|CSM(ISO8859_7),
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212)|CSM(GB2312)|CSM(KSC5601)|CSM(ISO8859_1)|CSM(ISO8859_7),
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)|CSM(JISX212)|CSM(GB2312)|CSM(KSC5601)|CSM(ISO8859_1)|CSM(ISO8859_7)
#else
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT),
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT),
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT),
CSM(ASCII)|CSM(JISX201)|CSM(JISX208)|CSM(HWKANA_7BIT)
#endif
};

Expand Down
14 changes: 12 additions & 2 deletions icu4c/source/common/unames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,11 @@ enumAlgNames(AlgorithmicRange *range,
uint16_t prefixLength, i, idx;

char c;

/* guard against invalid data */
if(count==0 || count>8) {
return true;
}

/* name = prefix factorized-elements */

Expand All @@ -1025,7 +1030,7 @@ enumAlgNames(AlgorithmicRange *range,
while(++start<limit) {
/* increment the indexes in lexical order bound by the factors */
i=count;
for (;;) {
while (i>0) {
idx = static_cast<uint16_t>(indexes[--i] + 1);
if(idx<factors[i]) {
/* skip one index and its element string */
Expand Down Expand Up @@ -1129,6 +1134,11 @@ findAlgName(AlgorithmicRange *range, UCharNameChoice nameChoice, const char *oth

char c;

/* guard against invalid data */
if(count==0 || count>8) {
return true;
}

/* name = prefix factorized-elements */

/* compare prefix */
Expand All @@ -1154,7 +1164,7 @@ findAlgName(AlgorithmicRange *range, UCharNameChoice nameChoice, const char *oth
while(++start<limit) {
/* increment the indexes in lexical order bound by the factors */
i=count;
for (;;) {
while (i>0) {
idx = static_cast<uint16_t>(indexes[--i] + 1);
if(idx<factors[i]) {
/* skip one index and its element string */
Expand Down
16 changes: 16 additions & 0 deletions icu4c/source/common/unisetspan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ class OffsetList { // Only ever stack-allocated, does not need to inherit UMemo
// If there is an offset equal to delta, it is removed.
// delta=[1..maxLength]
void shift(int32_t delta) {
// If OffsetList has zero capacity due to setMaxLength memory allocation error.
if (capacity == 0) {
return;
}
int32_t i=start+delta;
if(i>=capacity) {
i-=capacity;
Expand All @@ -107,6 +111,10 @@ class OffsetList { // Only ever stack-allocated, does not need to inherit UMemo
// Add an offset. The list must not contain it yet.
// offset=[1..maxLength]
void addOffset(int32_t offset) {
// If OffsetList has zero capacity due to setMaxLength memory allocation error.
if (capacity == 0) {
return;
}
int32_t i=start+offset;
if(i>=capacity) {
i-=capacity;
Expand All @@ -117,6 +125,10 @@ class OffsetList { // Only ever stack-allocated, does not need to inherit UMemo

// offset=[1..maxLength]
UBool containsOffset(int32_t offset) const {
// If OffsetList has zero capacity due to setMaxLength memory allocation error.
if (capacity == 0) {
return false;
}
int32_t i=start+offset;
if(i>=capacity) {
i-=capacity;
Expand All @@ -128,6 +140,10 @@ class OffsetList { // Only ever stack-allocated, does not need to inherit UMemo
// and reduce all other offsets by this minimum.
// Returns [1..maxLength].
int32_t popMinimum() {
// If OffsetList has zero capacity due to setMaxLength memory allocation error.
if (capacity == 0) {
return 0;
}
// Look for the next offset in list[start+1..capacity-1].
int32_t i=start, result;
while(++i<capacity) {
Expand Down
3 changes: 3 additions & 0 deletions icu4c/source/common/unormcmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ unorm_cmpEquivFold(const char16_t *s1, int32_t length1,
* the decomposition would replace the entire code point
*/
--s2;
if (s2==fold2) {
return c1-c2;
}
c2=*(s2-1);
}
}
Expand Down
4 changes: 4 additions & 0 deletions icu4c/source/common/ustrcase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,10 @@ static int32_t _cmpFold(
* the decomposition would replace the entire code point
*/
--s2;
if (s2==fold2) {
cmpRes=c1-c2;
break;
}
--m2;
c2=*(s2-1);
}
Expand Down
3 changes: 3 additions & 0 deletions icu4c/source/i18n/calendar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3324,6 +3324,9 @@ int32_t Calendar::computeZoneOffset(double millis, double millisInDay, UErrorCod
// 6 hour window would be sufficient for this purpose.
int32_t tmpRaw, tmpDst;
tz.getOffset(tgmt - 6*60*60*1000, false, tmpRaw, tmpDst, ec);
if (U_FAILURE(ec)) {
return 0;
}
int32_t offsetDelta = (rawOffset + dstOffset) - (tmpRaw + tmpDst);

U_ASSERT(offsetDelta < -6*60*60*1000);
Expand Down
3 changes: 3 additions & 0 deletions icu4c/source/i18n/collationweights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ setWeightByte(uint32_t weight, int32_t idx, uint32_t byte) {

static inline uint32_t
truncateWeight(uint32_t weight, int32_t length) {
if (length == 0) {
return 0;
}
return static_cast<uint32_t>(weight & (0xffffffff << (8 * (4 - length))));
}

Expand Down
6 changes: 6 additions & 0 deletions icu4c/source/i18n/nfrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,8 +604,14 @@ NFRuleSet::findFractionRuleSetRule(double number) const
int64_t numerator;
{
for (uint32_t i = 1; i < rules.size(); ++i) {
if (leastCommonMultiple == 0) {
return nullptr;
}
leastCommonMultiple = util_lcm(leastCommonMultiple, rules[i]->getBaseValue());
}
if (leastCommonMultiple == 0) {
return nullptr;
}
numerator = util64_fromDouble(number * static_cast<double>(leastCommonMultiple) + 0.5);
}
// for each rule, do the following...
Expand Down
7 changes: 7 additions & 0 deletions icu4c/source/i18n/rbt_pars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,13 @@ int32_t TransliteratorParser::syntaxError(UErrorCode parseErrorCode,
int32_t pos,
UErrorCode& status)
{
if (pos > rule.length()) {
pos = rule.length();
}
if (pos < 0) {
pos = 0;
}

parseError.offset = pos;
parseError.line = 0 ; /* we are not using line numbers */

Expand Down
3 changes: 3 additions & 0 deletions icu4c/source/i18n/stsearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ StringSearch * StringSearch::safeClone() const
getCollator(),
m_breakiterator_,
status);
if (U_FAILURE(status)) {
return nullptr;
}
/* test for nullptr */
if (result == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
Expand Down
3 changes: 3 additions & 0 deletions icu4c/source/i18n/tridpars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,9 @@ void U_CALLCONV TransliteratorIDParser::init(UErrorCode &status) {
ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, utrans_transliterator_cleanup);

SPECIAL_INVERSES = new Hashtable(true, status);
if (U_FAILURE(status)) {
return;
}
if (SPECIAL_INVERSES == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
Expand Down