Compare commits

...

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

22 changed files with 1248 additions and 708 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

8
.gitignore vendored
View File

@ -1 +1,7 @@
SOURCES/icu4c-60_3-src.tgz /icu4c-*-src.tgz
/icu4c-*-data.zip
/icu-config.sh
/metaZones.txt
/timezoneTypes.txt
/windowsZones.txt
/zoneinfo64.txt

View File

@ -1 +0,0 @@
83e6eb1931aac0aae6e313b306b3ca332c017bc3 SOURCES/icu4c-60_3-src.tgz

View File

@ -0,0 +1,390 @@
From af6fbac0bdba3080a8bcb5d12764d1fece2e9c1d Mon Sep 17 00:00:00 2001
From: Mike FABIAN <mfabian@redhat.com>
Date: Mon, 23 Aug 2021 18:03:31 +0200
Subject: [PATCH 1/2] ICU-21667 Fix coverity warnings
See: https://unicode-org.atlassian.net/browse/ICU-21667
(Issues found by coverity in icu-69.1)
---
source/common/brkiter.cpp | 2 +
source/common/serv.cpp | 76 +++++++++++++----------
source/common/serv.h | 5 ++
source/common/uloc_keytype.cpp | 8 +++
source/common/umutablecptrie.cpp | 2 +-
source/common/uresbund.cpp | 3 +-
source/i18n/decNumber.h | 2 +-
source/i18n/rbt_pars.cpp | 7 +--
source/i18n/tridpars.cpp | 1 +
source/i18n/usearch.cpp | 2 +
source/i18n/uspoof_impl.cpp | 6 +-
source/tools/gensprep/store.c | 1 -
source/tools/makeconv/genmbcs.cpp | 4 ++
source/tools/pkgdata/pkgtypes.c | 12 ++--
source/tools/toolutil/filetools.cpp | 1 +
15 files changed, 84 insertions(+), 48 deletions(-)
diff --git a/source/common/brkiter.cpp b/source/common/brkiter.cpp
index b452cf2c050..e2edbe8eaf6 100644
--- a/source/common/brkiter.cpp
+++ b/source/common/brkiter.cpp
@@ -107,7 +107,9 @@ BreakIterator::buildInstance(const Locale& loc, const char *type, UErrorCode &st
}
}
+ /* coverity[incorrect_free] */
ures_close(brkRules);
+ /* coverity[incorrect_free] */
ures_close(brkName);
UDataMemory* file = udata_open(U_ICUDATA_BRKITR, ext, fnbuff, &status);
diff --git a/source/common/serv.cpp b/source/common/serv.cpp
index 5248f7c192b..ddf17e45069 100644
--- a/source/common/serv.cpp
+++ b/source/common/serv.cpp
@@ -722,49 +722,57 @@ UVector&
ICUService::getDisplayNames(UVector& result,
const Locale& locale,
const UnicodeString* matchID,
- UErrorCode& status) const
+ UErrorCode& status) const
{
+ // cast away semantic const
+ return const_cast<ICUService *>(this)->getDisplayNamesImpl(result, locale, matchID, status);
+}
+
+UVector&
+ICUService::getDisplayNamesImpl(UVector& result,
+ const Locale& locale,
+ const UnicodeString* matchID,
+ UErrorCode& status)
+{
+ if (U_FAILURE(status)) { return result; }
result.removeAllElements();
result.setDeleter(userv_deleteStringPair);
- if (U_SUCCESS(status)) {
- ICUService* ncthis = (ICUService*)this; // cast away semantic const
- Mutex mutex(&lock);
+ Mutex mutex(&lock);
- if (dnCache != nullptr && dnCache->locale != locale) {
- delete dnCache;
- ncthis->dnCache = nullptr;
- }
+ if (dnCache != nullptr && dnCache->locale != locale) {
+ delete dnCache;
+ dnCache = nullptr;
+ }
+ if (dnCache == nullptr) {
+ const Hashtable* m = getVisibleIDMap(status);
+ if (U_FAILURE(status)) {
+ return result;
+ }
+ dnCache = new DNCache(locale);
if (dnCache == nullptr) {
- const Hashtable* m = getVisibleIDMap(status);
- if (U_FAILURE(status)) {
- return result;
- }
- ncthis->dnCache = new DNCache(locale);
- if (dnCache == nullptr) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return result;
- }
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return result;
+ }
- int32_t pos = UHASH_FIRST;
- const UHashElement* entry = nullptr;
- while ((entry = m->nextElement(pos)) != nullptr) {
- const UnicodeString* id = (const UnicodeString*)entry->key.pointer;
- ICUServiceFactory* f = (ICUServiceFactory*)entry->value.pointer;
- UnicodeString dname;
- f->getDisplayName(*id, locale, dname);
- if (dname.isBogus()) {
- status = U_MEMORY_ALLOCATION_ERROR;
- } else {
- dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap
- if (U_SUCCESS(status)) {
- continue;
- }
+ int32_t pos = UHASH_FIRST;
+ const UHashElement* entry = nullptr;
+ while ((entry = m->nextElement(pos)) != nullptr) {
+ const UnicodeString* id = static_cast<const UnicodeString*>(entry->key.pointer);
+ ICUServiceFactory* f = static_cast<ICUServiceFactory*>(entry->value.pointer);
+ UnicodeString dname;
+ f->getDisplayName(*id, locale, dname);
+ if (dname.isBogus()) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ dnCache->cache.put(dname, (void*)id, status); // share pointer with visibleIDMap
+ if (U_SUCCESS(status)) {
+ continue;
}
- delete dnCache;
- ncthis->dnCache = nullptr;
- return result;
}
+ delete dnCache;
+ dnCache = nullptr;
+ return result;
}
}
diff --git a/source/common/serv.h b/source/common/serv.h
index 9aea548fc3a..3c53f228738 100644
--- a/source/common/serv.h
+++ b/source/common/serv.h
@@ -759,6 +759,11 @@ class U_COMMON_API ICUService : public ICUNotifier {
const UnicodeString* matchID,
UErrorCode& status) const;
+ UVector& getDisplayNamesImpl(UVector& result,
+ const Locale& locale,
+ const UnicodeString* matchID,
+ UErrorCode& status);
+
/**
* <p>A convenience override of registerInstance(UObject*, const UnicodeString&, UBool)
* that defaults visible to true.</p>
diff --git a/source/common/uloc_keytype.cpp b/source/common/uloc_keytype.cpp
index a84b8609079..a837e0f14a7 100644
--- a/source/common/uloc_keytype.cpp
+++ b/source/common/uloc_keytype.cpp
@@ -327,12 +327,20 @@ initFromResourceBundle(UErrorCode& sts) {
}
}
if (U_FAILURE(sts)) {
+ if (typeDataMap != NULL) {
+ uhash_close(typeDataMap);
+ typeDataMap = NULL;
+ }
break;
}
LocExtKeyData* keyData = gLocExtKeyDataEntries->create();
if (keyData == nullptr) {
sts = U_MEMORY_ALLOCATION_ERROR;
+ if (typeDataMap != NULL) {
+ uhash_close(typeDataMap);
+ typeDataMap = NULL;
+ }
break;
}
keyData->bcpId = bcpKeyId;
diff --git a/source/common/umutablecptrie.cpp b/source/common/umutablecptrie.cpp
index cdbe27080b4..e58ab6f4897 100644
--- a/source/common/umutablecptrie.cpp
+++ b/source/common/umutablecptrie.cpp
@@ -1543,7 +1543,7 @@ int32_t MutableCodePointTrie::compactTrie(int32_t fastILimit, UErrorCode &errorC
MixedBlocks mixedBlocks;
int32_t newDataLength = compactData(fastILimit, newData, newDataCapacity,
dataNullIndex, mixedBlocks, errorCode);
- if (U_FAILURE(errorCode)) { return 0; }
+ if (U_FAILURE(errorCode)) { uprv_free(newData); return 0; }
U_ASSERT(newDataLength <= newDataCapacity);
uprv_free(data);
data = newData;
diff --git a/source/common/uresbund.cpp b/source/common/uresbund.cpp
index 5aa1c5fa2f1..7d16cd048ef 100644
--- a/source/common/uresbund.cpp
+++ b/source/common/uresbund.cpp
@@ -2927,7 +2927,8 @@ typedef struct ULocalesContext {
static void U_CALLCONV
ures_loc_closeLocales(UEnumeration *enumerator) {
- ULocalesContext *ctx = (ULocalesContext *)enumerator->context;
+ if (enumerator == nullptr) { return; }
+ ULocalesContext* ctx = (ULocalesContext *)(enumerator->context);
ures_close(&ctx->curr);
ures_close(&ctx->installed);
uprv_free(ctx);
diff --git a/source/i18n/decNumber.h b/source/i18n/decNumber.h
index 4a1eb364e19..6ad94386c1f 100644
--- a/source/i18n/decNumber.h
+++ b/source/i18n/decNumber.h
@@ -86,7 +86,7 @@
/* range: -1999999997 through 999999999 */
uint8_t bits; /* Indicator bits (see above) */
/* Coefficient, from least significant unit */
- decNumberUnit lsu[DECNUMUNITS];
+ decNumberUnit lsu[DECNUMUNITS+2];
} decNumber;
/* Notes: */
diff --git a/source/i18n/rbt_pars.cpp b/source/i18n/rbt_pars.cpp
index 10482d5edb1..c59a22faab2 100644
--- a/source/i18n/rbt_pars.cpp
+++ b/source/i18n/rbt_pars.cpp
@@ -552,16 +552,15 @@ int32_t RuleHalf::parseSection(const UnicodeString& rule, int32_t pos, int32_t l
case ALT_FUNCTION:
{
int32_t iref = pos;
- TransliteratorIDParser::SingleID* single =
- TransliteratorIDParser::parseFilterID(rule, iref);
+ LocalPointer<TransliteratorIDParser::SingleID> single(
+ TransliteratorIDParser::parseFilterID(rule, iref));
// The next character MUST be a segment open
- if (single == nullptr ||
+ if (single.isNull() ||
!ICU_Utility::parseChar(rule, iref, SEGMENT_OPEN)) {
return syntaxError(U_INVALID_FUNCTION, rule, start, status);
}
Transliterator *t = single->createInstance();
- delete single;
if (t == nullptr) {
return syntaxError(U_INVALID_FUNCTION, rule, start, status);
}
diff --git a/source/i18n/tridpars.cpp b/source/i18n/tridpars.cpp
index 6c23a0dc902..f9c3c207025 100644
--- a/source/i18n/tridpars.cpp
+++ b/source/i18n/tridpars.cpp
@@ -136,6 +136,7 @@ TransliteratorIDParser::parseSingleID(const UnicodeString& id, int32_t& pos,
specsB = parseFilterID(id, pos, true);
// Must close with a ')'
if (specsB == nullptr || !ICU_Utility::parseChar(id, pos, CLOSE_REV)) {
+ delete specsB;
delete specsA;
pos = start;
return nullptr;
diff --git a/source/i18n/usearch.cpp b/source/i18n/usearch.cpp
index 6d9b60cef72..1fb82fe26a4 100644
--- a/source/i18n/usearch.cpp
+++ b/source/i18n/usearch.cpp
@@ -199,6 +199,7 @@ inline int32_t * addTouint32_tArray(int32_t *destination,
int32_t *temp = (int32_t *)allocateMemory(
sizeof(int32_t) * newlength, status);
if (U_FAILURE(*status)) {
+ uprv_free(temp);
return nullptr;
}
uprv_memcpy(temp, destination, sizeof(int32_t) * (size_t)offset);
@@ -240,6 +241,7 @@ inline int64_t * addTouint64_tArray(int64_t *destination,
sizeof(int64_t) * newlength, status);
if (U_FAILURE(*status)) {
+ uprv_free(temp);
return nullptr;
}
diff --git a/source/i18n/uspoof_impl.cpp b/source/i18n/uspoof_impl.cpp
index 7a6084a1096..a1bd7d66a92 100644
--- a/source/i18n/uspoof_impl.cpp
+++ b/source/i18n/uspoof_impl.cpp
@@ -194,8 +194,12 @@ void SpoofImpl::setAllowedLocales(const char *localesList, UErrorCode &status) {
// Store the updated spoof checker state.
tmpSet = allowedChars.clone();
+ if (tmpSet == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
const char *tmpLocalesList = uprv_strdup(localesList);
- if (tmpSet == nullptr || tmpLocalesList == nullptr) {
+ if (tmpLocalesList == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
diff --git a/source/tools/gensprep/store.c b/source/tools/gensprep/store.c
index c3712febb4c..377877c94be 100644
--- a/source/tools/gensprep/store.c
+++ b/source/tools/gensprep/store.c
@@ -638,7 +638,6 @@ extern void
cleanUpData(void) {
uprv_free(mappingData);
utrie_close(sprepTrie);
- uprv_free(sprepTrie);
}
#endif /* #if !UCONFIG_NO_IDNA */
diff --git a/source/tools/makeconv/genmbcs.cpp b/source/tools/makeconv/genmbcs.cpp
index 43b96d814fb..0f610afeee4 100644
--- a/source/tools/makeconv/genmbcs.cpp
+++ b/source/tools/makeconv/genmbcs.cpp
@@ -173,6 +173,10 @@ MBCSOpen(UCMFile *ucm) {
}
MBCSInit(mbcsData, ucm);
+ /* The memory in the MBSData structure following
+ * newConverter will be properly freed in MBCSClose.
+ */
+ /* coverity[leaked_storage] */
return &mbcsData->newConverter;
}
diff --git a/source/tools/pkgdata/pkgtypes.c b/source/tools/pkgdata/pkgtypes.c
index 26bd945df73..ba516861a01 100644
--- a/source/tools/pkgdata/pkgtypes.c
+++ b/source/tools/pkgdata/pkgtypes.c
@@ -31,6 +31,7 @@ const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim,
{
int32_t ln = 0;
char buffer[1024];
+ char *bufferp = buffer;
while(l != NULL)
{
if(l->str)
@@ -43,7 +44,7 @@ const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim,
buffer[uprv_strlen(buffer)-1] = '\0';
}
if(buffer[0] == '"') {
- uprv_strcpy(buffer, buffer+1);
+ bufferp = buffer+1;
}
} else if(quote > 0) { /* add quotes */
if(l->str[0] != '"') {
@@ -54,7 +55,7 @@ const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim,
uprv_strcat(buffer, "\"");
}
}
- T_FileStream_write(s, buffer, (int32_t)uprv_strlen(buffer));
+ T_FileStream_write(s, bufferp, (int32_t)uprv_strlen(bufferp));
ln += (int32_t)uprv_strlen(l->str);
}
@@ -75,7 +76,8 @@ const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim,
const char *pkg_writeCharList(FileStream *s, CharList *l, const char *delim, int32_t quote)
{
- char buffer[1024];
+ char buffer[1026]; /* 1026 instead of 1024 because quotes may be added */
+ char *bufferp = buffer;
while(l != NULL)
{
if(l->str)
@@ -93,7 +95,7 @@ const char *pkg_writeCharList(FileStream *s, CharList *l, const char *delim, int
buffer[uprv_strlen(buffer)-1] = '\0';
}
if(buffer[0] == '"') {
- uprv_strcpy(buffer, buffer+1);
+ bufferp = buffer+1;
}
} else if(quote > 0) { /* add quotes */
if(l->str[0] != '"') {
@@ -104,7 +106,7 @@ const char *pkg_writeCharList(FileStream *s, CharList *l, const char *delim, int
uprv_strcat(buffer, "\"");
}
}
- T_FileStream_write(s, buffer, (int32_t)uprv_strlen(buffer));
+ T_FileStream_write(s, bufferp, (int32_t)uprv_strlen(bufferp));
}
if(l->next && delim)
diff --git a/source/tools/toolutil/filetools.cpp b/source/tools/toolutil/filetools.cpp
index 994d8e31f00..8dcbb6a480a 100644
--- a/source/tools/toolutil/filetools.cpp
+++ b/source/tools/toolutil/filetools.cpp
@@ -64,6 +64,7 @@ isFileModTimeLater(const char *filePath, const char *checkAgainst, UBool isDir)
newpath.append(dirEntry->d_name, -1, status);
if (U_FAILURE(status)) {
fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, u_errorName(status));
+ closedir(pDir);
return false;
}
--
2.46.1

View File

@ -0,0 +1,487 @@
From ac0192d1de167e11f2d8a28e2781941be4f60877 Mon Sep 17 00:00:00 2001
From: Mike FABIAN <mfabian@redhat.com>
Date: Mon, 19 Aug 2024 16:15:01 +0200
Subject: [PATCH 2/2] Fix coverity warnings icu-74.2
---
source/common/loclikelysubtags.cpp | 1 +
source/common/ubidi.cpp | 1 +
source/common/ubiditransform.cpp | 2 +-
source/common/ucnv.cpp | 3 ++-
source/common/ucnv2022.cpp | 2 ++
source/common/ucnv_u16.cpp | 2 ++
source/common/ucnv_u7.cpp | 1 +
source/common/ucnvmbcs.cpp | 1 +
source/common/ucnvscsu.cpp | 2 ++
source/common/umutablecptrie.cpp | 1 +
source/common/unames.cpp | 1 +
source/i18n/collationrootelements.cpp | 2 ++
source/i18n/dayperiodrules.cpp | 1 +
source/i18n/double-conversion-bignum.cpp | 3 +++
source/i18n/measfmt.cpp | 1 +
source/i18n/measunit.cpp | 3 +++
source/i18n/number_fluent.cpp | 1 +
source/i18n/number_padding.cpp | 1 +
source/i18n/number_rounding.cpp | 2 ++
source/i18n/number_skeletons.cpp | 1 +
source/i18n/numrange_fluent.cpp | 1 +
source/i18n/plurrule.cpp | 1 +
source/i18n/rbt_pars.cpp | 1 +
source/i18n/tzgnames.cpp | 1 +
source/i18n/vtzone.cpp | 2 +-
source/tools/gencnval/gencnval.c | 5 +++++
source/tools/genrb/wrtxml.cpp | 2 +-
source/tools/makeconv/makeconv.cpp | 4 ++++
source/tools/toolutil/package.cpp | 1 +
source/tools/toolutil/ucbuf.cpp | 2 +-
30 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/source/common/loclikelysubtags.cpp b/source/common/loclikelysubtags.cpp
index c2a7011b509..7943b6d2489 100644
--- a/source/common/loclikelysubtags.cpp
+++ b/source/common/loclikelysubtags.cpp
@@ -736,6 +736,7 @@ int32_t XLikelySubtags::getLikelyIndex(const char *language, const char *script)
int32_t value;
// Small optimization: Array lookup for first language letter.
int32_t c0;
+ /* coverity[overrun-local] */
if (0 <= (c0 = uprv_lowerOrdinal(language[0])) && c0 <= 25 &&
language[1] != 0 && // language.length() >= 2
(state = trieFirstLetterStates[c0]) != 0) {
diff --git a/source/common/ubidi.cpp b/source/common/ubidi.cpp
index fcf82fa97a8..18a179a15f7 100644
--- a/source/common/ubidi.cpp
+++ b/source/common/ubidi.cpp
@@ -1276,6 +1276,7 @@ resolveExplicitLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) {
} else
/* make it WS so that it is handled by adjustWSLevels() */
dirProps[i]=WS;
+ /* coverity[overrun-local] */
embeddingLevel=(UBiDiLevel)stack[stackLast]&~ISOLATE;
flags|=(DIRPROP_FLAG(ON)|DIRPROP_FLAG_LR(embeddingLevel));
previousLevel=embeddingLevel;
diff --git a/source/common/ubiditransform.cpp b/source/common/ubiditransform.cpp
index 01f5901a2c2..23634742b88 100644
--- a/source/common/ubiditransform.cpp
+++ b/source/common/ubiditransform.cpp
@@ -499,7 +499,7 @@ ubiditransform_transform(UBiDiTransform *pBiDiTransform,
/* Checking for U_SUCCESS() within the loop to bail out on first failure. */
for (action = pBiDiTransform->pActiveScheme->actions; *action && U_SUCCESS(*pErrorCode); action++) {
if ((*action)(pBiDiTransform, pErrorCode)) {
- if (action + 1) {
+ if (action[1] != nullptr) {
updateSrc(pBiDiTransform, pBiDiTransform->dest, *pBiDiTransform->pDestLength,
*pBiDiTransform->pDestLength, pErrorCode);
}
diff --git a/source/common/ucnv.cpp b/source/common/ucnv.cpp
index a7a07d65d61..87b4cd8ace5 100644
--- a/source/common/ucnv.cpp
+++ b/source/common/ucnv.cpp
@@ -105,7 +105,7 @@ ucnv_openU (const char16_t * name,
*err = U_ILLEGAL_ARGUMENT_ERROR;
return nullptr;
}
- return ucnv_open(u_austrcpy(asciiName, name), err);
+ return ucnv_open(u_austrncpy(asciiName, name, UCNV_MAX_CONVERTER_NAME_LENGTH), err);
}
/* Copy the string that is represented by the UConverterPlatform enum
@@ -2240,6 +2240,7 @@ ucnv_convertEx(UConverter *targetCnv, UConverter *sourceCnv,
}
/* The pivot buffer is empty; reset it so we start at pivotStart. */
+ /* coverity[escape_local_addr_alias] */
*pivotSource=*pivotTarget=pivotStart;
/*
diff --git a/source/common/ucnv2022.cpp b/source/common/ucnv2022.cpp
index 5989c1b405a..7d5b450d78a 100644
--- a/source/common/ucnv2022.cpp
+++ b/source/common/ucnv2022.cpp
@@ -3108,6 +3108,7 @@ UConverter_fromUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterFromUnicodeArgs* args
} else {
/* GB2312_1 or ISO-IR-165 */
U_ASSERT(cs0<UCNV_2022_MAX_CONVERTERS);
+ /* coverity[overrun-local] */
len2 = MBCS_FROM_UCHAR32_ISO2022(
converterData->myConverterArray[cs0],
sourceChar,
@@ -3392,6 +3393,7 @@ UConverter_toUnicode_ISO_2022_CN_OFFSETS_LOGIC(UConverterToUnicodeArgs *args,
}else{
U_ASSERT(tempState<UCNV_2022_MAX_CONVERTERS);
+ /* coverity[overrun-local] */
cnv = myData->myConverterArray[tempState];
tempBuf[0] = (char) (mySourceChar);
tempBuf[1] = (char) trailByte;
diff --git a/source/common/ucnv_u16.cpp b/source/common/ucnv_u16.cpp
index c3bcfef50cb..70dfbe89884 100644
--- a/source/common/ucnv_u16.cpp
+++ b/source/common/ucnv_u16.cpp
@@ -234,6 +234,7 @@ _UTF16BEFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
if(length>0) {
/* output length bytes with overflow (length>targetCapacity>0) */
+ /* coverity[uninit_use_in_call] */
ucnv_fromUWriteBytes(cnv,
overflow, length,
(char **)&target, pArgs->targetLimit,
@@ -835,6 +836,7 @@ _UTF16LEFromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
if(length>0) {
/* output length bytes with overflow (length>targetCapacity>0) */
+ /* coverity[uninit_use_in_call] */
ucnv_fromUWriteBytes(cnv,
overflow, length,
&target, pArgs->targetLimit,
diff --git a/source/common/ucnv_u7.cpp b/source/common/ucnv_u7.cpp
index 398b528e832..6df77253b12 100644
--- a/source/common/ucnv_u7.cpp
+++ b/source/common/ucnv_u7.cpp
@@ -617,6 +617,7 @@ _UTF7FromUnicodeWithOffsets(UConverterFromUnicodeArgs *pArgs,
base64Counter=1;
break;
case 1:
+ /* coverity[deref_overflow] */
*target++=toBase64[bits|(c>>14)];
if(target<targetLimit) {
*target++=toBase64[(c>>8)&0x3f];
diff --git a/source/common/ucnvmbcs.cpp b/source/common/ucnvmbcs.cpp
index d7606039800..9277ad25837 100644
--- a/source/common/ucnvmbcs.cpp
+++ b/source/common/ucnvmbcs.cpp
@@ -2839,6 +2839,7 @@ ucnv_MBCSToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
/* Back out bytes from the previous buffer: Need to replay them. */
cnv->preToULength=(int8_t)(bytesFromThisBuffer-backOutDistance);
/* preToULength is negative! */
+ /* coverity[overflow_sink] */
uprv_memcpy(cnv->preToU, bytes+i, -cnv->preToULength);
source=(const uint8_t *)pArgs->source;
}
diff --git a/source/common/ucnvscsu.cpp b/source/common/ucnvscsu.cpp
index 2138e289cad..30a1b69824b 100644
--- a/source/common/ucnvscsu.cpp
+++ b/source/common/ucnvscsu.cpp
@@ -402,6 +402,7 @@ _SCSUToUnicodeWithOffsets(UConverterToUnicodeArgs *pArgs,
case quoteOne:
if(b<0x80) {
/* all static offsets are in the BMP */
+ /* coverity[deref_overflow] */
*target++=(char16_t)(staticOffsets[quoteWindow]+b);
if(offsets!=nullptr) {
*offsets++=sourceIndex;
@@ -642,6 +643,7 @@ _SCSUToUnicode(UConverterToUnicodeArgs *pArgs,
*target++=(char16_t)b;
} else {
/* write from dynamic window */
+ /* coverity[deref_overflow] */
uint32_t c=scsu->toUDynamicOffsets[dynamicWindow]+(b&0x7f);
if(c<=0xffff) {
*target++=(char16_t)c;
diff --git a/source/common/umutablecptrie.cpp b/source/common/umutablecptrie.cpp
index e58ab6f4897..502dfad5a50 100644
--- a/source/common/umutablecptrie.cpp
+++ b/source/common/umutablecptrie.cpp
@@ -534,6 +534,7 @@ void MutableCodePointTrie::setRange(UChar32 start, UChar32 end, uint32_t value,
// Iterate over all-value blocks.
while (start < limit) {
int32_t i = start >> UCPTRIE_SHIFT_3;
+ /* coverity[overrun-local] */
if (flags[i] == ALL_SAME) {
index[i] = value;
} else /* MIXED */ {
diff --git a/source/common/unames.cpp b/source/common/unames.cpp
index 1b3192bf25e..c01c9d2db04 100644
--- a/source/common/unames.cpp
+++ b/source/common/unames.cpp
@@ -1561,6 +1561,7 @@ u_charFromName(UCharNameChoice nameChoice,
/* try extended names first */
if (lower[0] == '<') {
+ /* coverity[deref_overflow] */
if (nameChoice == U_EXTENDED_CHAR_NAME && lower[--i] == '>') {
// Parse a string like "<category-HHHH>" where HHHH is a hex code point.
uint32_t limit = i;
diff --git a/source/i18n/collationrootelements.cpp b/source/i18n/collationrootelements.cpp
index 9b46d14144b..54fa479617a 100644
--- a/source/i18n/collationrootelements.cpp
+++ b/source/i18n/collationrootelements.cpp
@@ -127,6 +127,7 @@ CollationRootElements::getSecondaryBefore(uint32_t p, uint32_t s) const {
} else {
index = findPrimary(p) + 1;
previousSec = Collation::BEFORE_WEIGHT16;
+ /* coverity[overflow_sink] */
sec = getFirstSecTerForPrimary(index) >> 16;
}
U_ASSERT(s >= sec);
@@ -157,6 +158,7 @@ CollationRootElements::getTertiaryBefore(uint32_t p, uint32_t s, uint32_t t) con
} else {
index = findPrimary(p) + 1;
previousTer = Collation::BEFORE_WEIGHT16;
+ /* coverity[overflow_sink] */
secTer = getFirstSecTerForPrimary(index);
}
uint32_t st = (s << 16) | t;
diff --git a/source/i18n/dayperiodrules.cpp b/source/i18n/dayperiodrules.cpp
index 294390cce2b..95befe8301c 100644
--- a/source/i18n/dayperiodrules.cpp
+++ b/source/i18n/dayperiodrules.cpp
@@ -218,6 +218,7 @@ struct DayPeriodRulesDataSink : public ResourceSink {
}
if (hour == 25) { hour = 0; }
if (cutoffs[hour] & (1 << CUTOFF_TYPE_BEFORE)) {
+ /* coverity[overrun-call] */
rule.add(startHour, hour, period);
break;
}
diff --git a/source/i18n/double-conversion-bignum.cpp b/source/i18n/double-conversion-bignum.cpp
index d2b701a21d8..77bab875aab 100644
--- a/source/i18n/double-conversion-bignum.cpp
+++ b/source/i18n/double-conversion-bignum.cpp
@@ -390,6 +390,7 @@ void Bignum::Square() {
// First shift the digits so we don't overwrite them.
const int copy_offset = used_bigits_;
for (int i = 0; i < used_bigits_; ++i) {
+ /* coverity[overrun-call] */
RawBigit(copy_offset + i) = RawBigit(i);
}
// We have two loops to avoid some 'if's in the loop.
@@ -415,7 +416,9 @@ void Bignum::Square() {
// Invariant: sum of both indices is again equal to i.
// Inner loop runs 0 times on last iteration, emptying accumulator.
while (bigit_index2 < used_bigits_) {
+ /* coverity[overrun-call] */
const Chunk chunk1 = RawBigit(copy_offset + bigit_index1);
+ /* coverity[overrun-call] */
const Chunk chunk2 = RawBigit(copy_offset + bigit_index2);
accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
bigit_index1--;
diff --git a/source/i18n/measfmt.cpp b/source/i18n/measfmt.cpp
index da4e69b49b7..09be56fcf33 100644
--- a/source/i18n/measfmt.cpp
+++ b/source/i18n/measfmt.cpp
@@ -516,6 +516,7 @@ UnicodeString &MeasureFormat::formatMeasurePerUnit(
.formatImpl(&result, status);
}
DecimalFormat::fieldPositionHelper(result, pos, appendTo.length(), status);
+ /* coverity[uninit_use_in_call] */
appendTo.append(result.toTempString(status));
return appendTo;
}
diff --git a/source/i18n/measunit.cpp b/source/i18n/measunit.cpp
index abb21997705..bff3e6273af 100644
--- a/source/i18n/measunit.cpp
+++ b/source/i18n/measunit.cpp
@@ -2230,6 +2230,7 @@ const char *MeasureUnit::getSubtype() const {
}
const char *MeasureUnit::getIdentifier() const {
+ /* coverity[negative_returns] */
return fImpl ? fImpl->identifier.data() : gSubTypes[getOffset()];
}
@@ -2340,6 +2341,7 @@ void MeasureUnit::initTime(const char *timeId) {
int32_t result = binarySearch(gTypes, 0, UPRV_LENGTHOF(gTypes), "duration");
U_ASSERT(result != -1);
fTypeId = result;
+ /* coverity[negative_returns] */
result = binarySearch(gSubTypes, gOffsets[fTypeId], gOffsets[fTypeId + 1], timeId);
U_ASSERT(result != -1);
fSubTypeId = result - gOffsets[fTypeId];
@@ -2349,6 +2351,7 @@ void MeasureUnit::initCurrency(StringPiece isoCurrency) {
int32_t result = binarySearch(gTypes, 0, UPRV_LENGTHOF(gTypes), "currency");
U_ASSERT(result != -1);
fTypeId = result;
+ /* coverity[negative_returns] */
result = binarySearch(
gSubTypes, gOffsets[fTypeId], gOffsets[fTypeId + 1], isoCurrency);
if (result == -1) {
diff --git a/source/i18n/number_fluent.cpp b/source/i18n/number_fluent.cpp
index 45d6b06c6df..e6fe49f0dca 100644
--- a/source/i18n/number_fluent.cpp
+++ b/source/i18n/number_fluent.cpp
@@ -466,6 +466,7 @@ LocalizedNumberFormatter::LocalizedNumberFormatter(LocalizedNumberFormatter&& sr
LocalizedNumberFormatter::LocalizedNumberFormatter(NFS<LNF>&& src) noexcept
: NFS<LNF>(std::move(src)) {
+ // coverity[use_after_move]
lnfMoveHelper(std::move(static_cast<LNF&&>(src)));
}
diff --git a/source/i18n/number_padding.cpp b/source/i18n/number_padding.cpp
index c320c3ffb6f..3aa996f932f 100644
--- a/source/i18n/number_padding.cpp
+++ b/source/i18n/number_padding.cpp
@@ -29,6 +29,7 @@ addPaddingHelper(UChar32 paddingCp, int32_t requiredPadding, FormattedStringBuil
}
Padder::Padder(UChar32 cp, int32_t width, UNumberFormatPadPosition position) : fWidth(width) {
+ fUnion.errorCode = U_ZERO_ERROR; /* avoid coverity warning: "fUnion uninitialized" */
// TODO(13034): Consider making this a string instead of code point.
fUnion.padding.fCp = cp;
fUnion.padding.fPosition = position;
diff --git a/source/i18n/number_rounding.cpp b/source/i18n/number_rounding.cpp
index e6bb509ffd7..d9fe7d74275 100644
--- a/source/i18n/number_rounding.cpp
+++ b/source/i18n/number_rounding.cpp
@@ -284,6 +284,7 @@ FractionPrecision Precision::constructFraction(int32_t minFrac, int32_t maxFrac)
settings.fMinSig = -1;
settings.fMaxSig = -1;
PrecisionUnion union_;
+ /* coverity[uninit_use] */
union_.fracSig = settings;
return {RND_FRACTION, union_};
}
@@ -295,6 +296,7 @@ Precision Precision::constructSignificant(int32_t minSig, int32_t maxSig) {
settings.fMinSig = static_cast<digits_t>(minSig);
settings.fMaxSig = static_cast<digits_t>(maxSig);
PrecisionUnion union_;
+ /* coverity[uninit_use] */
union_.fracSig = settings;
return {RND_SIGNIFICANT, union_};
}
diff --git a/source/i18n/number_skeletons.cpp b/source/i18n/number_skeletons.cpp
index ef3befbffad..d790db5b92d 100644
--- a/source/i18n/number_skeletons.cpp
+++ b/source/i18n/number_skeletons.cpp
@@ -545,6 +545,7 @@ MacroProps skeleton::parseSkeleton(
segment.resetLength();
if (U_FAILURE(status)) {
errOffset = segment.getOffset();
+ /* coverity[uninit_use_in_call] */
return macros;
}
diff --git a/source/i18n/numrange_fluent.cpp b/source/i18n/numrange_fluent.cpp
index 0944f3024ff..bdf179170a3 100644
--- a/source/i18n/numrange_fluent.cpp
+++ b/source/i18n/numrange_fluent.cpp
@@ -239,6 +239,7 @@ LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(LocalizedNumberRang
LocalizedNumberRangeFormatter::LocalizedNumberRangeFormatter(NFS<LNF>&& src) noexcept
: NFS<LNF>(std::move(src)) {
// Steal the compiled formatter
+ // coverity[use_after_move]
LNF&& _src = static_cast<LNF&&>(src);
auto* stolen = _src.fAtomicFormatter.exchange(nullptr);
delete fAtomicFormatter.exchange(stolen);
diff --git a/source/i18n/plurrule.cpp b/source/i18n/plurrule.cpp
index 839d14147cc..cc842347875 100644
--- a/source/i18n/plurrule.cpp
+++ b/source/i18n/plurrule.cpp
@@ -343,6 +343,7 @@ PluralRules::select(const number::impl::UFormattedNumberRangeData* impl, UErrorC
return ICU_Utility::makeBogusString();
}
auto result = mStandardPluralRanges->resolve(form1, form2);
+ /* coverity[overrun-call] */
return UnicodeString(StandardPlural::getKeyword(result), -1, US_INV);
}
diff --git a/source/i18n/rbt_pars.cpp b/source/i18n/rbt_pars.cpp
index c59a22faab2..1a49eaf12fb 100644
--- a/source/i18n/rbt_pars.cpp
+++ b/source/i18n/rbt_pars.cpp
@@ -1059,6 +1059,7 @@ void TransliteratorParser::parseRules(const UnicodeString& rule,
setVariableRange(0xF000, 0xF8FF, status);
}
+ /* coverity[overflow_sink] */
if (resemblesPragma(rule, pos, limit)) {
int32_t ppp = parsePragma(rule, pos, limit, status);
if (ppp < 0) {
diff --git a/source/i18n/tzgnames.cpp b/source/i18n/tzgnames.cpp
index d55b0fd2ae0..1e14003b22b 100644
--- a/source/i18n/tzgnames.cpp
+++ b/source/i18n/tzgnames.cpp
@@ -517,6 +517,7 @@ TZGNCore::getGenericLocationName(const UnicodeString& tzCanonicalID) {
char16_t tzIDKey[ZID_KEY_MAX + 1];
int32_t tzIDKeyLen = tzCanonicalID.extract(tzIDKey, ZID_KEY_MAX + 1, status);
U_ASSERT(status == U_ZERO_ERROR); // already checked length above
+ /* coverity[negative_returns] */
tzIDKey[tzIDKeyLen] = 0;
const char16_t *locname = (const char16_t *)uhash_get(fLocationNamesMap, tzIDKey);
diff --git a/source/i18n/vtzone.cpp b/source/i18n/vtzone.cpp
index 25af556aa22..7b557f1dab8 100644
--- a/source/i18n/vtzone.cpp
+++ b/source/i18n/vtzone.cpp
@@ -119,7 +119,7 @@ static UnicodeString& appendAsciiDigits(int32_t number, uint8_t length, UnicodeS
number *= -1;
}
- length = length > 10 ? 10 : length;
+ length = (uint8_t)((length > 10) ? 10 : length);
if (length == 0) {
// variable length
i = 0;
diff --git a/source/tools/gencnval/gencnval.c b/source/tools/gencnval/gencnval.c
index 54b41fb57da..129cf1fc451 100644
--- a/source/tools/gencnval/gencnval.c
+++ b/source/tools/gencnval/gencnval.c
@@ -273,6 +273,11 @@ main(int argc, char* argv[]) {
const char* sourcedir = options[SOURCEDIR].value;
if (sourcedir != NULL && *sourcedir != 0) {
+ if (strlen(sourcedir) + strlen(path) + 1 >= 512) {
+ fprintf(stderr,
+ "Length of sourcedir + path is too long, must be <= 510.\n");
+ exit(U_ILLEGAL_ARGUMENT_ERROR);
+ }
char *end;
uprv_strcpy(pathBuf, sourcedir);
end = uprv_strchr(pathBuf, 0);
diff --git a/source/tools/genrb/wrtxml.cpp b/source/tools/genrb/wrtxml.cpp
index 16f67fabcaf..cd0bb19bff7 100644
--- a/source/tools/genrb/wrtxml.cpp
+++ b/source/tools/genrb/wrtxml.cpp
@@ -187,7 +187,7 @@ static void strnrepchr(char* src, int32_t srcLen, char s, char r){
*/
static char* parseFilename(const char* id, char* /*lang*/) {
int idLen = (int) uprv_strlen(id);
- char* localeID = (char*) uprv_malloc(idLen);
+ char* localeID = (char*) uprv_malloc(idLen+1);
int pos = 0;
int canonCapacity = 0;
char* canon = nullptr;
diff --git a/source/tools/makeconv/makeconv.cpp b/source/tools/makeconv/makeconv.cpp
index b14b4316f3b..e47033f7c59 100644
--- a/source/tools/makeconv/makeconv.cpp
+++ b/source/tools/makeconv/makeconv.cpp
@@ -377,6 +377,10 @@ int main(int argc, char* argv[])
data.staticData.name);
}
+ if (strlen(cnvName) + 1 > UPRV_LENGTHOF(data.staticData.name)) {
+ fprintf(stderr, "converter name %s too long\n", cnvName);
+ return U_BUFFER_OVERFLOW_ERROR;
+ }
uprv_strcpy((char*)data.staticData.name, cnvName);
if(!uprv_isInvariantString((char*)data.staticData.name, -1)) {
diff --git a/source/tools/toolutil/package.cpp b/source/tools/toolutil/package.cpp
index 3098f5d57d4..3bd28e48ac1 100644
--- a/source/tools/toolutil/package.cpp
+++ b/source/tools/toolutil/package.cpp
@@ -865,6 +865,7 @@ Package::writePackage(const char *filename, char outType, const char *comment) {
// write the items
for(pItem=items, i=0; i<itemCount; ++pItem, ++i) {
int32_t type=makeTypeEnum(pItem->type);
+ /* coverity[negative_returns] */
if(ds[type]!=nullptr) {
// swap each item from its platform properties to the desired ones
udata_swap(
diff --git a/source/tools/toolutil/ucbuf.cpp b/source/tools/toolutil/ucbuf.cpp
index 1eb54e260e6..1999433b003 100644
--- a/source/tools/toolutil/ucbuf.cpp
+++ b/source/tools/toolutil/ucbuf.cpp
@@ -257,7 +257,7 @@ ucbuf_fillucbuf( UCHARBUF* buf,UErrorCode* error){
/* for post-context */
start = pos+len;
- stop = (int32_t)(((pos+CONTEXT_LEN)<= (sourceLimit-cbuf) )? (pos+(CONTEXT_LEN-1)) : (sourceLimit-cbuf));
+ stop = (int32_t)(((pos+CONTEXT_LEN)<= (int32_t)(sourceLimit-cbuf) )? (pos+(CONTEXT_LEN-1)) : (int32_t)(sourceLimit-cbuf));
memcpy(postContext,source,stop-start);
/* null terminate the buffer */
--
2.46.2

View File

@ -1,108 +0,0 @@
From 23d76d88630ecee02515e2c8f5c8769cc795ae23 Mon Sep 17 00:00:00 2001
From: Shane Carr <shane@unicode.org>
Date: Fri, 23 Mar 2018 00:56:16 +0000
Subject: [PATCH] ICU-13634 Adding integer overflow logic to ICU4C number
pipeline in places where it is in ICU4J.
X-SVN-Rev: 41136
diff --git a/icu4c/source/common/putil.cpp b/icu4c/source/common/putil.cpp
index 83f08ac070..452e2fd79c 100644
--- a/icu4c/source/common/putil.cpp
+++ b/icu4c/source/common/putil.cpp
@@ -533,6 +533,30 @@ uprv_fmin(double x, double y)
return (x > y ? y : x);
}
+#include <iostream>
+
+U_CAPI UBool U_EXPORT2
+uprv_add32_overflow(int32_t a, int32_t b, int32_t* res) {
+ // NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_add_overflow.
+ // This function could be optimized by calling one of those primitives.
+ auto a64 = static_cast<int64_t>(a);
+ auto b64 = static_cast<int64_t>(b);
+ int64_t res64 = a64 + b64;
+ *res = static_cast<int32_t>(res64);
+ return res64 != *res;
+}
+
+U_CAPI UBool U_EXPORT2
+uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res) {
+ // NOTE: Some compilers (GCC, Clang) have primitives available, like __builtin_mul_overflow.
+ // This function could be optimized by calling one of those primitives.
+ auto a64 = static_cast<int64_t>(a);
+ auto b64 = static_cast<int64_t>(b);
+ int64_t res64 = a64 * b64;
+ *res = static_cast<int32_t>(res64);
+ return res64 != *res;
+}
+
/**
* Truncates the given double.
* trunc(3.3) = 3.0, trunc (-3.3) = -3.0
diff --git a/icu4c/source/common/putilimp.h b/icu4c/source/common/putilimp.h
index eb9b5380f1..8b858df9e3 100644
--- a/icu4c/source/common/putilimp.h
+++ b/icu4c/source/common/putilimp.h
@@ -391,6 +391,32 @@ U_INTERNAL double U_EXPORT2 uprv_log(double d);
*/
U_INTERNAL double U_EXPORT2 uprv_round(double x);
+/**
+ * Adds the signed integers a and b, storing the result in res.
+ * Checks for signed integer overflow.
+ * Similar to the GCC/Clang extension __builtin_add_overflow
+ *
+ * @param a The first operand.
+ * @param b The second operand.
+ * @param res a + b
+ * @return true if overflow occurred; false if no overflow occurred.
+ * @internal
+ */
+U_INTERNAL UBool U_EXPORT2 uprv_add32_overflow(int32_t a, int32_t b, int32_t* res);
+
+/**
+ * Multiplies the signed integers a and b, storing the result in res.
+ * Checks for signed integer overflow.
+ * Similar to the GCC/Clang extension __builtin_mul_overflow
+ *
+ * @param a The first multiplicand.
+ * @param b The second multiplicand.
+ * @param res a * b
+ * @return true if overflow occurred; false if no overflow occurred.
+ * @internal
+ */
+U_INTERNAL UBool U_EXPORT2 uprv_mul32_overflow(int32_t a, int32_t b, int32_t* res);
+
#if 0
/**
* Returns the number of digits after the decimal point in a double number x.
diff --git a/icu4c/source/test/cintltst/putiltst.c b/icu4c/source/test/cintltst/putiltst.c
index b99d9fca9c..1c3e073041 100644
--- a/icu4c/source/test/cintltst/putiltst.c
+++ b/icu4c/source/test/cintltst/putiltst.c
@@ -128,6 +128,20 @@ static void TestPUtilAPI(void){
log_err("ERROR: uprv_isInfinite failed.\n");
}
+ log_verbose("Testing the APIs uprv_add32_overflow and uprv_mul32_overflow\n");
+ int32_t overflow_result;
+ doAssert(FALSE, uprv_add32_overflow(INT32_MAX - 2, 1, &overflow_result), "should not overflow");
+ doAssert(INT32_MAX - 1, overflow_result, "should equal INT32_MAX - 1");
+ doAssert(FALSE, uprv_add32_overflow(INT32_MAX - 2, 2, &overflow_result), "should not overflow");
+ doAssert(INT32_MAX, overflow_result, "should equal exactly INT32_MAX");
+ doAssert(TRUE, uprv_add32_overflow(INT32_MAX - 2, 3, &overflow_result), "should overflow");
+ doAssert(FALSE, uprv_mul32_overflow(INT32_MAX / 5, 4, &overflow_result), "should not overflow");
+ doAssert(INT32_MAX / 5 * 4, overflow_result, "should equal INT32_MAX / 5 * 4");
+ doAssert(TRUE, uprv_mul32_overflow(INT32_MAX / 5, 6, &overflow_result), "should overflow");
+ // Test on negative numbers:
+ doAssert(FALSE, uprv_add32_overflow(-3, -2, &overflow_result), "should not overflow");
+ doAssert(-5, overflow_result, "should equal -5");
+
#if 0
log_verbose("Testing the API uprv_digitsAfterDecimal()....\n");
doAssert(uprv_digitsAfterDecimal(value1), 3, "uprv_digitsAfterDecimal() failed.");
--
2.24.1

View File

@ -1,103 +0,0 @@
diff -ru icu/source/common/unistr.cpp icu.new/source/common/unistr.cpp
--- icu/source/common/unistr.cpp 2019-04-12 00:26:16.000000000 +0200
+++ icu.new/source/common/unistr.cpp 2020-03-03 15:39:37.069874709 +0100
@@ -1544,7 +1544,11 @@
}
int32_t oldLength = length();
- int32_t newLength = oldLength + srcLength;
+ int32_t newLength;
+ if (uprv_add32_overflow(oldLength, srcLength, &newLength)) {
+ setToBogus();
+ return *this;
+ }
// optimize append() onto a large-enough, owned string
if((newLength <= getCapacity() && isBufferWritable()) ||
cloneArrayIfNeeded(newLength, getGrowCapacity(newLength))) {
diff -ru icu/source/test/intltest/ustrtest.cpp icu.new/source/test/intltest/ustrtest.cpp
--- icu/source/test/intltest/ustrtest.cpp 2019-04-12 00:26:16.000000000 +0200
+++ icu.new/source/test/intltest/ustrtest.cpp 2020-03-03 15:44:59.059239188 +0100
@@ -64,6 +64,7 @@
TESTCASE_AUTO(TestUInt16Pointers);
TESTCASE_AUTO(TestWCharPointers);
TESTCASE_AUTO(TestNullPointers);
+ TESTCASE_AUTO(TestLargeAppend);
TESTCASE_AUTO_END;
}
@@ -2248,3 +2249,64 @@
UnicodeString(u"def").extract(nullptr, 0, errorCode);
assertEquals("buffer overflow extracting to nullptr", U_BUFFER_OVERFLOW_ERROR, errorCode);
}
+
+void UnicodeStringTest::TestLargeAppend() {
+ if(quick) return;
+
+ IcuTestErrorCode status(*this, "TestLargeAppend");
+ // Make a large UnicodeString
+ int32_t len = 0xAFFFFFF;
+ UnicodeString str;
+ char16_t *buf = str.getBuffer(len);
+ // A fast way to set buffer to valid Unicode.
+ // 4E4E is a valid unicode character
+ uprv_memset(buf, 0x4e, len * 2);
+ str.releaseBuffer(len);
+ UnicodeString dest;
+ // Append it 16 times
+ // 0xAFFFFFF times 16 is 0xA4FFFFF1,
+ // which is greater than INT32_MAX, which is 0x7FFFFFFF.
+ int64_t total = 0;
+ for (int32_t i = 0; i < 16; i++) {
+ dest.append(str);
+ total += len;
+ if (total <= INT32_MAX) {
+ assertFalse("dest is not bogus", dest.isBogus());
+ } else {
+ assertTrue("dest should be bogus", dest.isBogus());
+ }
+ }
+ dest.remove();
+ total = 0;
+ for (int32_t i = 0; i < 16; i++) {
+ dest.append(str);
+ total += len;
+ if (total + len <= INT32_MAX) {
+ assertFalse("dest is not bogus", dest.isBogus());
+ } else if (total <= INT32_MAX) {
+ // Check that a string of exactly the maximum size works
+ UnicodeString str2;
+ int32_t remain = INT32_MAX - total;
+ char16_t *buf2 = str2.getBuffer(remain);
+ if (buf2 == nullptr) {
+ // if somehow memory allocation fail, return the test
+ return;
+ }
+ uprv_memset(buf2, 0x4e, remain * 2);
+ str2.releaseBuffer(remain);
+ dest.append(str2);
+ total += remain;
+ assertEquals("When a string of exactly the maximum size works", (int64_t)INT32_MAX, total);
+ assertEquals("When a string of exactly the maximum size works", INT32_MAX, dest.length());
+ assertFalse("dest is not bogus", dest.isBogus());
+
+ // Check that a string size+1 goes bogus
+ str2.truncate(1);
+ dest.append(str2);
+ total++;
+ assertTrue("dest should be bogus", dest.isBogus());
+ } else {
+ assertTrue("dest should be bogus", dest.isBogus());
+ }
+ }
+}
diff -ru icu/source/test/intltest/ustrtest.h icu.new/source/test/intltest/ustrtest.h
--- icu/source/test/intltest/ustrtest.h 2019-04-12 00:26:16.000000000 +0200
+++ icu.new/source/test/intltest/ustrtest.h 2020-03-03 15:45:36.147935611 +0100
@@ -96,6 +96,7 @@
void TestUInt16Pointers();
void TestWCharPointers();
void TestNullPointers();
+ void TestLargeAppend();
};
#endif

View File

@ -1,96 +0,0 @@
diff -ru orig.icu/source/test/cintltst/cnmdptst.c icu/source/test/cintltst/cnmdptst.c
--- orig.icu/source/test/cintltst/cnmdptst.c 2016-03-23 21:48:18.000000000 +0100
+++ icu/source/test/cintltst/cnmdptst.c 2016-04-15 18:34:06.148251985 +0200
@@ -186,6 +186,12 @@
/* Test exponential pattern*/
static void TestExponential(void)
{
+/* erAck: fails on armv7hl, https://bugzilla.redhat.com/show_bug.cgi?id=1239574 */
+#if 1
+ /* Actually only 3 tests fail, but given the nested structure depending on
+ * array sizes there's no simple "disable this and that". */
+ return;
+#endif
int32_t pat_length, val_length, lval_length;
int32_t ival, ilval, p, v, lneed;
UNumberFormat *fmt;
diff -ru orig.icu/source/test/intltest/dcfmtest.cpp icu/source/test/intltest/dcfmtest.cpp
--- orig.icu/source/test/intltest/dcfmtest.cpp 2016-03-23 21:48:38.000000000 +0100
+++ icu/source/test/intltest/dcfmtest.cpp 2016-04-15 18:34:06.148251985 +0200
@@ -279,6 +279,13 @@
//
formatLineMat.reset(testLine);
if (formatLineMat.lookingAt(status)) {
+/* erAck: fails on armv7hl, https://bugzilla.redhat.com/show_bug.cgi?id=1239574 */
+#if 1
+// [Formattable] file dcfmtest.txt, line 62: expected "12.35E5", got "1.235E6"
+// [StringPiece] file dcfmtest.txt, line 62: expected "12.35E5", got "1.235E6"
+ if (lineNum == 62)
+ continue;
+#endif
execFormatTest(lineNum,
formatLineMat.group(1, status), // Pattern
formatLineMat.group(2, status), // rounding mode
diff -ru orig.icu/source/test/intltest/numfmtspectest.cpp icu/source/test/intltest/numfmtspectest.cpp
--- orig.icu/source/test/intltest/numfmtspectest.cpp 2016-03-23 21:48:40.000000000 +0100
+++ icu/source/test/intltest/numfmtspectest.cpp 2016-04-15 18:34:06.148251985 +0200
@@ -137,11 +137,14 @@
void NumberFormatSpecificationTest::TestScientificNotation() {
assertPatternFr("1,23E4", 12345.0, "0.00E0", TRUE);
+/* erAck: fails on armv7hl, https://bugzilla.redhat.com/show_bug.cgi?id=1239574 */
+#if 0
assertPatternFr("123,00E2", 12300.0, "000.00E0", TRUE);
assertPatternFr("123,0E2", 12300.0, "000.0#E0", TRUE);
assertPatternFr("123,0E2", 12300.1, "000.0#E0", TRUE);
assertPatternFr("123,01E2", 12301.0, "000.0#E0", TRUE);
assertPatternFr("123,01E+02", 12301.0, "000.0#E+00", TRUE);
+#endif
assertPatternFr("12,3E3", 12345.0, "##0.00E0", TRUE);
assertPatternFr("12,300E3", 12300.1, "##0.0000E0", TRUE);
assertPatternFr("12,30E3", 12300.1, "##0.000#E0", TRUE);
@@ -221,6 +224,8 @@
assertEquals("", "USD (433.22)", result, TRUE);
}
}
+/* erAck: fails on armv7hl, https://bugzilla.redhat.com/show_bug.cgi?id=1239574 */
+#if 0
const char *paddedSciPattern = "QU**00.#####E0";
assertPatternFr("QU***43,3E-1", 4.33, paddedSciPattern, TRUE);
{
@@ -242,6 +247,7 @@
}
// padding cannot work as intended with scientific notation.
assertPatternFr("QU**43,32E-1", 4.332, paddedSciPattern, TRUE);
+#endif
}
void NumberFormatSpecificationTest::assertPatternFr(
diff -ru orig.icu/source/test/intltest/numfmtst.cpp icu/source/test/intltest/numfmtst.cpp
--- orig.icu/source/test/intltest/numfmtst.cpp 2016-03-23 21:48:40.000000000 +0100
+++ icu/source/test/intltest/numfmtst.cpp 2016-04-15 18:34:06.150251997 +0200
@@ -730,6 +730,12 @@
void
NumberFormatTest::TestExponential(void)
{
+/* erAck: fails on armv7hl, https://bugzilla.redhat.com/show_bug.cgi?id=1239574 */
+#if 1
+ /* Actually only 3 tests fail, but given the nested structure depending on
+ * array sizes there's no simple "disable this and that". */
+ return;
+#endif
UErrorCode status = U_ZERO_ERROR;
DecimalFormatSymbols sym(Locale::getUS(), status);
if (U_FAILURE(status)) { errcheckln(status, "FAIL: Bad status returned by DecimalFormatSymbols ct - %s", u_errorName(status)); return; }
@@ -1846,8 +1852,11 @@
(int32_t) 45678000, "5E7", status);
expect(new DecimalFormat("00E0", US, status),
(int32_t) 45678000, "46E6", status);
+/* erAck: fails on armv7hl, https://bugzilla.redhat.com/show_bug.cgi?id=1239574 */
+#if 0
expect(new DecimalFormat("000E0", US, status),
(int32_t) 45678000, "457E5", status);
+#endif
/*
expect(new DecimalFormat("###E0", US, status),
new Object[] { new Double(0.0000123), "12.3E-6",

View File

@ -1,11 +0,0 @@
#!/bin/sh
OOO_ARCH=$(uname -m)
case $OOO_ARCH in
x86_64 | s390x | ppc64 | sparc64 | aarch64 | ppc64le | mips64 | mips64el)
bits=64
;;
* )
bits=32
;;
esac
exec icu-config-$bits "$@"

View File

@ -1,171 +0,0 @@
diff -urN icu.old/source/common/uloc_keytype.cpp icu/source/common/uloc_keytype.cpp
--- icu.old/source/common/uloc_keytype.cpp 2017-02-01 01:21:30.000000000 +0530
+++ icu/source/common/uloc_keytype.cpp 2018-09-23 18:48:04.414990551 +0530
@@ -383,6 +383,7 @@
LocExtKeyData* keyData = (LocExtKeyData*)uprv_malloc(sizeof(LocExtKeyData));
if (keyData == NULL) {
sts = U_MEMORY_ALLOCATION_ERROR;
+ uprv_free(typeDataMap);
break;
}
keyData->bcpId = bcpKeyId;
diff -urN icu.old/source/common/uloc_tag.cpp icu/source/common/uloc_tag.cpp
--- icu.old/source/common/uloc_tag.cpp 2017-10-11 21:54:34.000000000 +0530
+++ icu/source/common/uloc_tag.cpp 2018-09-23 18:48:58.207182317 +0530
@@ -2145,6 +2145,7 @@
error:
ultag_close(t);
+ uprv_free(pExtension);
return NULL;
}
diff -urN icu.old/source/i18n/olsontz.cpp icu/source/i18n/olsontz.cpp
--- icu.old/source/i18n/olsontz.cpp 2017-02-01 01:21:27.000000000 +0530
+++ icu/source/i18n/olsontz.cpp 2018-09-23 18:52:02.140418739 +0530
@@ -787,6 +787,7 @@
if (historicRules[typeIdx] == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
deleteTransitionRules();
+ uprv_free(times);
return;
}
}
diff -urN icu.old/source/i18n/rbt_pars.cpp icu/source/i18n/rbt_pars.cpp
--- icu.old/source/i18n/rbt_pars.cpp 2017-02-01 01:21:27.000000000 +0530
+++ icu/source/i18n/rbt_pars.cpp 2018-09-23 18:52:51.362679180 +0530
@@ -557,6 +557,7 @@
// The next character MUST be a segment open
if (single == NULL ||
!ICU_Utility::parseChar(rule, iref, SEGMENT_OPEN)) {
+ uprv_free(single);
return syntaxError(U_INVALID_FUNCTION, rule, start, status);
}
diff -urN icu.old/source/i18n/tznames_impl.cpp icu/source/i18n/tznames_impl.cpp
--- icu.old/source/i18n/tznames_impl.cpp 2017-10-11 21:54:34.000000000 +0530
+++ icu/source/i18n/tznames_impl.cpp 2018-09-23 18:55:36.222152997 +0530
@@ -1762,6 +1762,7 @@
UResourceBundle* rbTable = NULL;
rbTable = ures_getByKey(rb, key, rbTable, &status);
if (U_FAILURE(status)) {
+ uprv_free(rbTable);
return NULL;
}
@@ -1784,6 +1785,7 @@
if (names != NULL) {
uprv_free(names);
}
+ uprv_free(rbTable);
return NULL;
}
diff -urN icu.old/source/i18n/usearch.cpp icu/source/i18n/usearch.cpp
--- icu.old/source/i18n/usearch.cpp 2017-02-01 01:21:27.000000000 +0530
+++ icu/source/i18n/usearch.cpp 2018-09-23 18:54:34.752103865 +0530
@@ -222,6 +222,7 @@
int32_t *temp = (int32_t *)allocateMemory(
sizeof(int32_t) * newlength, status);
if (U_FAILURE(*status)) {
+ uprv_free(temp);
return NULL;
}
uprv_memcpy(temp, destination, sizeof(int32_t) * (size_t)offset);
@@ -263,6 +264,7 @@
sizeof(int64_t) * newlength, status);
if (U_FAILURE(*status)) {
+ uprv_free(temp);
return NULL;
}
diff -urN icu.old/source/tools/ctestfw/ctest.c icu/source/tools/ctestfw/ctest.c
--- icu.old/source/tools/ctestfw/ctest.c 2017-02-01 01:21:30.000000000 +0530
+++ icu/source/tools/ctestfw/ctest.c 2018-09-23 18:19:43.612734248 +0530
@@ -803,6 +803,7 @@
}
va_start(ap, pattern);
vlog_err(NULL, pattern, ap);
+ va_end(ap);
}
UBool T_CTEST_EXPORT2
@@ -810,6 +811,7 @@
va_list ap;
va_start(ap, pattern);
return vlog_knownIssue(ticket, pattern, ap);
+ va_end(ap);
}
void T_CTEST_EXPORT2
@@ -843,6 +845,7 @@
}
vlog_err(NULL, pattern, ap); /* no need for prefix in default case */
}
+ va_end(ap);
}
void T_CTEST_EXPORT2
@@ -852,6 +855,7 @@
va_start(ap, pattern);
vlog_info(NULL, pattern, ap);
+ va_end(ap);
}
void T_CTEST_EXPORT2
@@ -861,6 +865,7 @@
va_start(ap, pattern);
vlog_verbose(NULL, pattern, ap);
+ va_end(ap);
}
@@ -882,6 +887,7 @@
} else {
vlog_info("[DATA] ", pattern, ap);
}
+ va_end(ap);
}
diff -urN icu.old/source/tools/gensprep/store.c icu/source/tools/gensprep/store.c
--- icu.old/source/tools/gensprep/store.c 2017-02-08 00:27:35.000000000 +0530
+++ icu/source/tools/gensprep/store.c 2018-09-23 17:42:52.262908882 +0530
@@ -634,7 +634,6 @@
cleanUpData(void) {
uprv_free(mappingData);
utrie_close(sprepTrie);
- uprv_free(sprepTrie);
}
#endif /* #if !UCONFIG_NO_IDNA */
diff -urN icu.old/source/tools/pkgdata/pkgdata.cpp icu/source/tools/pkgdata/pkgdata.cpp
--- icu.old/source/tools/pkgdata/pkgdata.cpp 2017-03-23 04:56:34.000000000 +0530
+++ icu/source/tools/pkgdata/pkgdata.cpp 2018-09-23 17:40:19.730240502 +0530
@@ -1531,11 +1531,11 @@
gencFilePath);
result = runCommand(cmd);
- uprv_free(cmd);
if (result != 0) {
fprintf(stderr, "Error creating with assembly code. Failed command: %s\n", cmd);
return result;
}
+ uprv_free(cmd);
return pkg_generateLibraryFile(targetDir, mode, tempObjectFile);
}
diff -urN icu.old/source/tools/toolutil/filetools.cpp icu/source/tools/toolutil/filetools.cpp
--- icu.old/source/tools/toolutil/filetools.cpp 2017-02-01 01:21:30.000000000 +0530
+++ icu/source/tools/toolutil/filetools.cpp 2018-09-23 16:09:47.949491516 +0530
@@ -64,6 +64,7 @@
newpath.append(dirEntry->d_name, -1, status);
if (U_FAILURE(status)) {
fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, u_errorName(status));
+ free(pDir);
return FALSE;
};

View File

@ -1,154 +0,0 @@
Index: icu4c/source/test/intltest/tzregts.cpp
===================================================================
--- icu4c/source/test/intltest/tzregts.cpp (リビジョン 40953)
+++ icu4c/source/test/intltest/tzregts.cpp (リビジョン 40954)
@@ -12,6 +12,7 @@
#include "unicode/simpletz.h"
#include "unicode/smpdtfmt.h"
#include "unicode/strenum.h"
+#include "unicode/gregocal.h"
#include "tzregts.h"
#include "calregts.h"
#include "cmemory.h"
@@ -46,6 +47,7 @@
CASE(16, TestJDK12API);
CASE(17, Test4176686);
CASE(18, Test4184229);
+ CASE(19, TestNegativeDaylightSaving);
default: name = ""; break;
}
}
@@ -709,10 +711,10 @@
int32_t DATA [] = {
1, GOOD,
0, BAD,
- -1, BAD,
+ -1, GOOD, // #13566 updates SimpleTimeZone to support negative DST saving amount
60*60*1000, GOOD,
- INT32_MIN, BAD,
- // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time
+ INT32_MAX, GOOD, // no upper limit on DST savings at this time
+ INT32_MIN, GOOD // no lower limit as well
};
UErrorCode status = U_ZERO_ERROR;
@@ -1206,4 +1208,61 @@
delete zone;
}
+void TimeZoneRegressionTest::TestNegativeDaylightSaving() {
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t stdOff = 1 * 60*60*1000; // Standard offset UTC+1
+ int save = -1 * 60*60*1000; // DST saving amount -1 hour
+ SimpleTimeZone stzDublin(stdOff, "Dublin-2018",
+ UCAL_OCTOBER, -1, -UCAL_SUNDAY, 2*60*60*1000,
+ UCAL_MARCH, -1, -UCAL_SUNDAY, 1*60*60*1000,
+ save, status);
+ failure(status, "SimpleTimeZone constructor");
+
+ if (save != stzDublin.getDSTSavings()) {
+ errln((UnicodeString)"FAIL: DST saving is not " + save);
+ }
+
+ GregorianCalendar cal(* TimeZone::getGMT(), status);
+ failure(status, "GregorianCalendar constructor");
+
+ UDate testDate;
+ int32_t rawOffset;
+ int32_t dstOffset;
+
+ cal.set(2018, UCAL_JANUARY, 15, 0, 0, 0);
+ testDate = cal.getTime(status);
+ failure(status, "calendar getTime() - Jan 15");
+
+ if (!stzDublin.inDaylightTime(testDate, status)) {
+ errln("FAIL: The test date (Jan 15) must be in DST.");
+ }
+ failure(status, "inDaylightTime() - Jan 15");
+
+ stzDublin.getOffset(testDate, FALSE, rawOffset, dstOffset, status);
+ failure(status, "getOffset() - Jan 15");
+ if (rawOffset != stdOff || dstOffset != save) {
+ errln((UnicodeString)"FAIL: Expected [stdoff=" + stdOff + ",save=" + save
+ + "] on the test date (Jan 15), actual[stdoff=" + rawOffset
+ + ",save=" + dstOffset + "]");
+ }
+
+ cal.set(2018, UCAL_JULY, 15, 0, 0, 0);
+ testDate = cal.getTime(status);
+ failure(status, "calendar getTime() - Jul 15");
+
+ if (stzDublin.inDaylightTime(testDate, status)) {
+ errln("FAIL: The test date (Jul 15) must be in DST.");
+ }
+ failure(status, "inDaylightTime() - Jul 15");
+
+ stzDublin.getOffset(testDate, FALSE, rawOffset, dstOffset, status);
+ failure(status, "getOffset() - Jul 15");
+ if (rawOffset != stdOff || dstOffset != 0) {
+ errln((UnicodeString)"FAIL: Expected [stdoff=" + stdOff + ",save=" + 0
+ + "] on the test date (Jul 15), actual[stdoff=" + rawOffset
+ + ",save=" + dstOffset + "]");
+ }
+}
+
+
#endif /* #if !UCONFIG_NO_FORMATTING */
Index: icu4c/source/test/intltest/tzregts.h
===================================================================
--- icu4c/source/test/intltest/tzregts.h (リビジョン 40953)
+++ icu4c/source/test/intltest/tzregts.h (リビジョン 40954)
@@ -49,6 +49,7 @@
void TestJDK12API(void);
void Test4184229(void);
UBool checkCalendar314(GregorianCalendar *testCal, TimeZone *testTZ);
+ void TestNegativeDaylightSaving(void);
protected:
Index: icu4c/source/i18n/simpletz.cpp
===================================================================
--- icu4c/source/i18n/simpletz.cpp (リビジョン 40953)
+++ icu4c/source/i18n/simpletz.cpp (リビジョン 40954)
@@ -177,7 +177,7 @@
decodeRules(status);
- if (savingsDST <= 0) {
+ if (savingsDST == 0) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
}
@@ -686,7 +686,7 @@
void
SimpleTimeZone::setDSTSavings(int32_t millisSavedDuringDST, UErrorCode& status)
{
- if (millisSavedDuringDST <= 0) {
+ if (millisSavedDuringDST == 0) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
else {
Index: icu4c/source/i18n/unicode/simpletz.h
===================================================================
--- icu4c/source/i18n/unicode/simpletz.h (リビジョン 40953)
+++ icu4c/source/i18n/unicode/simpletz.h (リビジョン 40954)
@@ -647,7 +647,8 @@
* Sets the amount of time in ms that the clock is advanced during DST.
* @param millisSavedDuringDST the number of milliseconds the time is
* advanced with respect to standard time when the daylight savings rules
- * are in effect. A positive number, typically one hour (3600000).
+ * are in effect. Typically one hour (+3600000). The amount could be negative,
+ * but not 0.
* @param status An UErrorCode to receive the status.
* @stable ICU 2.0
*/
@@ -657,7 +658,8 @@
* Returns the amount of time in ms that the clock is advanced during DST.
* @return the number of milliseconds the time is
* advanced with respect to standard time when the daylight savings rules
- * are in effect. A positive number, typically one hour (3600000).
+ * are in effect. Typically one hour (+3600000). The amount could be negative,
+ * but not 0.
* @stable ICU 2.0
*/
virtual int32_t getDSTSavings(void) const;

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: desktop-qe.desktop-ci.tier1-gating.functional}

View File

@ -1,27 +1,40 @@
#%%global debugtrace 1 #%%global debugtrace 1
# Set to 0 when upgrading to a new ICU release that contains up-to-date timezone data.
# (or update the timezone data update..).
%global use_tzdata_update 0
%define version_dash %{gsub %{version} %. -}
%define version_underscore %{gsub %{version} %. _}
Name: icu Name: icu
Version: 60.3 Version: 74.2
Release: 2%{?dist} Release: 4%{?dist}
Summary: International Components for Unicode Summary: International Components for Unicode
License: MIT and UCD and Public Domain License: Unicode-DFS-2016 AND BSD-2-Clause AND BSD-3-Clause AND LicenseRef-Fedora-Public-Domain
URL: http://site.icu-project.org/ URL: http://site.icu-project.org/
Source0: https://github.com/unicode-org/icu/releases/download/release-60-3/icu4c-60_3-src.tgz Source0: https://github.com/unicode-org/icu/releases/download/release-%{version_dash}/icu4c-%{version_underscore}-src-FIXED.tgz
Source1: icu-config.sh %if 0%{?use_tzdata_update}
Source1: https://github.com/unicode-org/icu/releases/download/release-%{version_dash}/icu4c-%{version_underscore}-data.zip
Source2: https://raw.githubusercontent.com/unicode-org/icu-data/main/tzdata/icunew/2022b/44/metaZones.txt
Source3: https://raw.githubusercontent.com/unicode-org/icu-data/main/tzdata/icunew/2022b/44/timezoneTypes.txt
Source4: https://raw.githubusercontent.com/unicode-org/icu-data/main/tzdata/icunew/2022b/44/windowsZones.txt
Source5: https://raw.githubusercontent.com/unicode-org/icu-data/main/tzdata/icunew/2022b/44/zoneinfo64.txt
%endif
Source10: icu-config.sh
BuildRequires: gcc BuildRequires: gcc
BuildRequires: gcc-c++ BuildRequires: gcc-c++
BuildRequires: doxygen, autoconf, python3 BuildRequires: doxygen, autoconf, python3
BuildRequires: make
Requires: lib%{name}%{?_isa} = %{version}-%{release} Requires: lib%{name}%{?_isa} = %{version}-%{release}
Patch4: gennorm2-man.patch Patch4: gennorm2-man.patch
Patch5: icuinfo-man.patch Patch5: icuinfo-man.patch
Patch6: negative-daylight-savings.patch
Patch100: armv7hl-disable-tests.patch Patch10: 0001-ICU-21667-Fix-coverity-warnings.patch
Patch101: icu-covscan.patch Patch11: 0002-Fix-coverity-warnings-icu-74.2.patch
Patch200: ICU-13634-Adding-integer-overflow-logic-to-ICU4C-num.patch
Patch201: ICU-20958-Prevent-SEGV_MAPERR-in-append.patch
%description %description
Tools and utilities for developing with icu. Tools and utilities for developing with icu.
@ -61,16 +74,14 @@ BuildArch: noarch
%prep %prep
%setup -q -n %{name} %autosetup -p1 -n %{name}
%patch4 -p1 -b .gennorm2-man.patch %if 0%{?use_tzdata_update}
%patch5 -p1 -b .icuinfo-man.patch pushd source
%patch6 -p1 -b .negative-daylight-savings.patch unzip -o %{SOURCE1}
%ifarch armv7hl rm -f data/in/icudt*l.dat
%patch100 -p1 -b .armv7hl-disable-tests.patch cp -v -f %{SOURCE2} %{SOURCE3} %{SOURCE4} %{SOURCE5} data/misc
popd
%endif %endif
%patch101 -p1 -b .covscan
%patch200 -p2 -b .ICU-13634
%patch201 -p1 -b .ICU-20958
%build %build
pushd source pushd source
@ -87,7 +98,7 @@ OPTIONS='--with-data-packaging=library --disable-samples'
%if 0%{?debugtrace} %if 0%{?debugtrace}
OPTIONS=$OPTIONS' --enable-debug --enable-tracing' OPTIONS=$OPTIONS' --enable-debug --enable-tracing'
%endif %endif
%configure $OPTIONS CC=gcc CXX=g++ %configure $OPTIONS
#rhbz#225896 #rhbz#225896
sed -i 's|-nodefaultlibs -nostdlib||' config/mh-linux sed -i 's|-nodefaultlibs -nostdlib||' config/mh-linux
@ -103,20 +114,20 @@ test -f uconfig.h.prepend && sed -e '/^#define __UCONFIG_H__/ r uconfig.h.prepen
# more verbosity for build.log # more verbosity for build.log
sed -i -r 's|(PKGDATA_OPTS = )|\1-v |' data/Makefile sed -i -r 's|(PKGDATA_OPTS = )|\1-v |' data/Makefile
make %{?_smp_mflags} VERBOSE=1 %make_build
make %{?_smp_mflags} doc %make_build doc
%install %install
rm -rf $RPM_BUILD_ROOT source/__docs rm -rf $RPM_BUILD_ROOT source/__docs
make %{?_smp_mflags} -C source install DESTDIR=$RPM_BUILD_ROOT %make_install %{?_smp_mflags} -C source
make %{?_smp_mflags} -C source install-doc docdir=__docs make %{?_smp_mflags} -C source install-doc docdir=__docs
chmod +x $RPM_BUILD_ROOT%{_libdir}/*.so.* chmod +x $RPM_BUILD_ROOT%{_libdir}/*.so.*
( (
cd $RPM_BUILD_ROOT%{_bindir} cd $RPM_BUILD_ROOT%{_bindir}
mv icu-config icu-config-%{__isa_bits} mv icu-config icu-config-%{__isa_bits}
) )
install -p -m755 -D %{SOURCE1} $RPM_BUILD_ROOT%{_bindir}/icu-config install -p -m755 -D %{SOURCE10} $RPM_BUILD_ROOT%{_bindir}/icu-config
%check %check
@ -124,23 +135,13 @@ install -p -m755 -D %{SOURCE1} $RPM_BUILD_ROOT%{_bindir}/icu-config
if grep -q @VERSION@ source/tools/*/*.8 source/tools/*/*.1 source/config/*.1; then if grep -q @VERSION@ source/tools/*/*.8 source/tools/*/*.1 source/config/*.1; then
exit 1 exit 1
fi fi
%ifarch i686 %make_build -C source check
# F26 since the mass rebuild in 2017-Feb fails a check, ignore error. TODO: find cause / disable only one.
make %{?_smp_mflags} -C source check ||:
%else
make %{?_smp_mflags} -C source check
%endif
# log available codes # log available codes
pushd source pushd source
LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
%post -n lib%{name} -p /sbin/ldconfig
%postun -n lib%{name} -p /sbin/ldconfig
%files %files
%license license.html %license license.html
%exclude %{_datadir}/%{name}/*/LICENSE %exclude %{_datadir}/%{name}/*/LICENSE
@ -150,16 +151,18 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
%{_bindir}/gencnval %{_bindir}/gencnval
%{_bindir}/gendict %{_bindir}/gendict
%{_bindir}/genrb %{_bindir}/genrb
%{_bindir}/icuexportdata
%{_bindir}/makeconv %{_bindir}/makeconv
%{_bindir}/pkgdata %{_bindir}/pkgdata
%{_bindir}/uconv %{_bindir}/uconv
%{_sbindir}/* %{_sbindir}/*
%{_mandir}/man1/derb.1* %{_mandir}/man1/derb.1*
%{_mandir}/man1/genbrk.1*
%{_mandir}/man1/gencfu.1* %{_mandir}/man1/gencfu.1*
%{_mandir}/man1/gencnval.1* %{_mandir}/man1/gencnval.1*
%{_mandir}/man1/gendict.1* %{_mandir}/man1/gendict.1*
%{_mandir}/man1/genrb.1* %{_mandir}/man1/genrb.1*
%{_mandir}/man1/genbrk.1* %{_mandir}/man1/icuexportdata.1*
%{_mandir}/man1/makeconv.1* %{_mandir}/man1/makeconv.1*
%{_mandir}/man1/pkgdata.1* %{_mandir}/man1/pkgdata.1*
%{_mandir}/man1/uconv.1* %{_mandir}/man1/uconv.1*
@ -194,31 +197,136 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
%changelog %changelog
* Tue Mar 03 2020 Mike FABIAN <mfabian@redhat.com> - 60.3-2 * Tue Oct 29 2024 Troy Dawson <tdawson@redhat.com> - 74.2-4
- Apply ICU-13634-Adding-integer-overflow-logic-to-ICU4C-num.patch - Bump release for October 2024 mass rebuild:
- Apply ICU-20958-Prevent-SEGV_MAPERR-in-append.patch Resolves: RHEL-64018
- Resolves: rhbz#1808238
* Tue May 07 2019 Mike FABIAN <mfabian@redhat.com> - 60.3-1 * Fri Sep 20 2024 Mike FABIAN <mfabian@redhat.com> - 74.2-3
- Update to 60.3 maintenance release including support for new Japanese era Reiwa (令和). - Resolves: RHEL-59365 Fix coverity warnings
- Resolves: rhbz#1677093
* Thu Nov 15 2018 Parag Nemade <pnemade AT redhat DOT com> - 60.2-7 * Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 74.2-2
- Resolves:rh#1602551 - Fix specfile by adding compile options - Bump release for June 2024 mass rebuild
- also add BuildRequires for gcc and gcc-c++
- Correct the upstream URL
* Sun Sep 23 2018 Parag Nemade <pnemade AT redhat DOT com> - 60.2-6 * Wed Jan 31 2024 Pete Walter <pwalter@fedoraproject.org> - 74.2-1
- Resolves:rh#1602551 - Fix some covscan issues - Update to 74.2
* Thu Jun 28 2018 Mike FABIAN <mfabian@redhat.com> - 60.2-5 * Mon Jan 29 2024 Pete Walter <pwalter@fedoraproject.org> - 74.1-1
- Drop Python2 build dependency, use Python3 instead - Update to 74.1
- Resolves: rhbz#1595790
* Thu May 31 2018 Mike FABIAN <mfabian@redhat.com> - 60.2-4 * Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 73.2-5
- Add negative-daylight-savings.patch from upstream. - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
(see http://bugs.icu-project.org/trac/ticket/13566 and
http://bugs.icu-project.org/trac/changeset/40954) * Sat Jan 20 2024 Fedora Release Engineering <releng@fedoraproject.org> - 73.2-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Wed Dec 13 2023 Yaakov Selkowitz <yselkowi@redhat.com> - 73.2-3
- Fix broken TestHebrewCalendarInTemporalLeapYear
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 73.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Thu Jul 06 2023 Frantisek Zatloukal <fzatlouk@redhat.com> - 73.2-1
- Update to 73.2
* Fri Jan 20 2023 Eike Rathke <erack@redhat.com> - 72.1-3
- migrated to SPDX license IDs
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 72.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Wed Dec 28 2022 Pete Walter <pwalter@fedoraproject.org> - 72.1-1
- Update to 72.1
* Fri Sep 23 2022 Mike FABIAN <mfabian@redhat.com> - 71.1-2
- Update timezone data to 2022b
* Wed Jul 27 2022 Frantisek Zatloukal <fzatlouk@redhat.com> - 71.1-1
- Update to 71.1
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 69.1-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Thu May 05 2022 Mike FABIAN <mfabian@redhat.com> - 69.1-6
- Update timezone data to 2022a
* Wed Feb 02 2022 Eike Rathke <erack@redhat.com> - 69.1-5
- Introduce use_tzdata_update flag
* Tue Feb 01 2022 Mike FABIAN <mfabian@redhat.com> - 69.1-4
- Update timezone data to 2021a4
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 69.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 69.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Wed May 19 2021 Pete Walter <pwalter@fedoraproject.org> - 69.1-1
- Update to 69.1
* Tue Mar 30 2021 Jonathan Wakely <jwakely@redhat.com> - 67.1-6
- Rebuilt for removed libstdc++ symbol (#1937698)
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 67.1-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 67.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jul 21 2020 Eike Rathke <erack@redhat.com> - 67.1-3
- Replace unversioned %%{__python} macro with %%{__python3}
* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> - 67.1-2
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Fri May 15 2020 Pete Walter <pwalter@fedoraproject.org> - 67.1-1
- Update to 67.1
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 65.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Fri Nov 01 2019 Pete Walter <pwalter@fedoraproject.org> - 65.1-1
- Update to 65.1
- Add a patch from gentoo to fix the build on s390x
- Drop arm test disabling patches as they are no longer needed
* Fri Nov 01 2019 Pete Walter <pwalter@fedoraproject.org> - 63.2-4
- Build with Python 3
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 63.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon May 13 2019 Eike Rathke <erack@redhat.com> - 63.2-2
- Resolves: rhbz#1708935 temporarily roll back to 63.1
* Thu May 09 2019 Eike Rathke <erack@redhat.com> - 63.2-1
- Update to 63.2
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 63.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Jan 23 2019 Pete Walter <pwalter@fedoraproject.org> - 63.1-1
- Update to 63.1
* Tue Nov 06 2018 Eike Rathke <erack@redhat.com> - 62.1-3
- Resolves: rhbz#1646703 CVE-2018-18928
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 62.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jul 10 2018 Pete Walter <pwalter@fedoraproject.org> - 62.1-1
- Update to 62.1
* Mon May 28 2018 Eike Rathke <erack@redhat.com> - 61.1-2
- Resolves: rhbz#1582611 Add riscv64 to icu-config.sh
* Tue Apr 24 2018 Eike Rathke <erack@redhat.com> - 61.1-1
- Update to 61.1
* Thu Mar 15 2018 Iryna Shcherbina <ishcherb@redhat.com> - 60.2-3
- Update Python 2 dependency declarations to new packaging standards
(See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3)
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 60.2-2 * Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 60.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
@ -521,7 +629,7 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
- drop integrated icu.icu5557.safety.patch - drop integrated icu.icu5557.safety.patch
* Thu Nov 20 2008 Caolán McNamara <caolanm@redhat.com> - 4.0-4 * Thu Nov 20 2008 Caolán McNamara <caolanm@redhat.com> - 4.0-4
- annoyingly upstream tarball was repacked apparently to remove - annoyingly upstream tarball was repacked apparently to remove
some unused/cached dirs some unused/cached dirs
* Sat Sep 06 2008 Caolán McNamara <caolanm@redhat.com> - 4.0-3 * Sat Sep 06 2008 Caolán McNamara <caolanm@redhat.com> - 4.0-3
@ -546,7 +654,7 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
- drop integrated icu.regexp.patch - drop integrated icu.regexp.patch
* Mon May 19 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-8 * Mon May 19 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-8
- add icu.icu6284.strictalias.patch and build with - add icu.icu6284.strictalias.patch and build with
strict-aliasing strict-aliasing
* Tue Mar 18 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-7 * Tue Mar 18 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-7
@ -557,7 +665,7 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
- Resolves: rhbz#437761 add icu.icu6213.bengali.worstcase.patch - Resolves: rhbz#437761 add icu.icu6213.bengali.worstcase.patch
* Mon Feb 04 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-5 * Mon Feb 04 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-5
- Resolves: rhbz#431401 split syllables on 1st 0d4d of a 0d4d + - Resolves: rhbz#431401 split syllables on 1st 0d4d of a 0d4d +
(>= 0d15 && <= 0d39) + 0d4d + 0d30 sequence (>= 0d15 && <= 0d39) + 0d4d + 0d30 sequence
* Thu Jan 31 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-4 * Thu Jan 31 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-4
@ -570,7 +678,7 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
* Fri Jan 11 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-2 * Fri Jan 11 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-2
- remove icu.icu5365.dependantvowels.patch and cleanup - remove icu.icu5365.dependantvowels.patch and cleanup
icu.icu5506.multiplevowels.patch as they patch and unpatch icu.icu5506.multiplevowels.patch as they patch and unpatch
eachother (thanks George Rhoten for pointing out that madness) eachother (thanks George Rhoten for pointing out that madness)
* Fri Jan 11 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-1 * Fri Jan 11 2008 Caolán McNamara <caolanm@redhat.com> - 3.8.1-1
@ -611,7 +719,7 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
- drop integrated icu.icu5465.telegu.patch - drop integrated icu.icu5465.telegu.patch
* Wed Jun 13 2007 Caolán McNamara <caolanm@redhat.com> - 3.6-20 * Wed Jun 13 2007 Caolán McNamara <caolanm@redhat.com> - 3.6-20
- Resolves: rhbz#243984 change the icu group as it is libicu - Resolves: rhbz#243984 change the icu group as it is libicu
which is "System Environment/Libraries" not icu which is "System Environment/Libraries" not icu
* Mon Apr 30 2007 Caolán McNamara <caolanm@redhat.com> - 3.6-19 * Mon Apr 30 2007 Caolán McNamara <caolanm@redhat.com> - 3.6-19
@ -668,7 +776,7 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
- rh#206615# render malayam like pango - rh#206615# render malayam like pango
* Wed Sep 06 2006 Caolán McNamara <caolanm@redhat.com> - 3.6-2 * Wed Sep 06 2006 Caolán McNamara <caolanm@redhat.com> - 3.6-2
- fix rh#205252#/icu#5365 (gnome#121882#/#icu#4026#) to make icu - fix rh#205252#/icu#5365 (gnome#121882#/#icu#4026#) to make icu
like pango for multiple dependant vowels like pango for multiple dependant vowels
* Sun Sep 03 2006 Caolán McNamara <caolanm@redhat.com> - 3.6-1 * Sun Sep 03 2006 Caolán McNamara <caolanm@redhat.com> - 3.6-1
@ -721,7 +829,7 @@ LD_LIBRARY_PATH=lib:stubdata:tools/ctestfw:$LD_LIBRARY_PATH bin/uconv -l
* Wed Aug 31 2005 Thorsten Leemhuis <fedora at leemhuis.info> - 3.4-3 * Wed Aug 31 2005 Thorsten Leemhuis <fedora at leemhuis.info> - 3.4-3
- Use dist - Use dist
- gcc32 does not understand -fstack-protector and - gcc32 does not understand -fstack-protector and
--param=ssp-buffer-size=4 --param=ssp-buffer-size=4
* Tue Aug 2 2005 Ville Skyttä <ville.skytta at iki.fi> - 3.4-2 * Tue Aug 2 2005 Ville Skyttä <ville.skytta at iki.fi> - 3.4-2

5
plans/basic.fmf Normal file
View File

@ -0,0 +1,5 @@
summary: Basic smoke test
discover:
how: fmf
execute:
how: tmt

3
rpminspect.yaml Normal file
View File

@ -0,0 +1,3 @@
debuginfo:
ignore:
- /usr/lib/debug/usr/lib*/libicudata.so*

7
sources Normal file
View File

@ -0,0 +1,7 @@
SHA512 (metaZones.txt) = 339876ea759f84dcd77017a7592b12777f60f7556fda4f2d29fcfb674d816893d6ad9f91f8422fbf5746472fbeb15f4247446e37b5a6056ab2a662c204d7cf39
SHA512 (timezoneTypes.txt) = 11fa693a0cc1a232ea23befdf9906f04896190210e85ecad82cd7b7dbdeb289dc6e2602a6d18bb035d7a7f7cbfaf8e57e7bbcd290fb10220751eaa7e7ebf500b
SHA512 (windowsZones.txt) = 0244076828692df657b48f05d0f1537ae0fb08f5f91ef8858e08097ce5df70363e11594ca24c735e71620504b68241ae4901a481ad59f1b6ec6b9eb28a30eda5
SHA512 (zoneinfo64.txt) = 289ac8dbdcdf39221d0cc41562134270433210658acd57d20c3ba3d727bfeba007ddcc7123634300b7a93cccafe8bb367f8c134e3414dc00d0dd309a29dd9373
SHA512 (icu-config.sh) = 04e00dbbd40c84ef355f149ab8d20dd0fa7fa7abacac849ea065ebab5de2746c13626e61f2a543c5207aa246a5805d2d9e64be9221a40eb8314d720c7824d314
SHA512 (icu4c-74_2-src-FIXED.tgz) = e6c7876c0f3d756f3a6969cad9a8909e535eeaac352f3a721338b9cbd56864bf7414469d29ec843462997815d2ca9d0dab06d38c37cdd4d8feb28ad04d8781b0
SHA512 (icu4c-74_2-data.zip) = f9dbd303f78de1bf9089262211f3b618f1ec915e57877855d0bc6496332620f4ea92eabe1dff9fa721600e9a6ce56885f79361bbcdf97d0cfedd18e4a2d58ad0

1
tests/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
timezone-sample

9
tests/main.fmf Normal file
View File

@ -0,0 +1,9 @@
summary: Test cases for libicu
test: bash runtest.sh
framework: beakerlib
duration: 5m
require:
- gcc-c++
- make
- libicu-devel

27
tests/runtest.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash
# Include Beaker environment
. /usr/share/beakerlib/beakerlib.sh || exit 1
rlJournalStart
rlPhaseStartSetup
rlAssertRpm "libicu"
rlAssertRpm "libicu-devel"
rlRun "g++ -g -O0 $(icu-config --cppflags --cxxflags --ldflags --ldflags-icuio) -o timezone-sample timezone-sample.cpp"
rlRun "TmpDir=\`mktemp -d\`" 0 "Creating tmp directory"
rlRun "cp timezone-sample $TmpDir"
rlRun "pushd $TmpDir"
rlPhaseEnd
rlPhaseStartTest
rlLog "Run timezone-sample"
rlRun -l "./timezone-sample" 0 "Running timezone tests"
rlPhaseEnd
rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

134
tests/timezone-sample.cpp Normal file
View File

@ -0,0 +1,134 @@
#include <stdio.h>
#include <unicode/utypes.h>
#include <unicode/unistr.h>
#include <unicode/calendar.h>
#include <unicode/ustdio.h>
#include <unicode/datefmt.h>
#include <unicode/locid.h>
using namespace icu;
int fail_count = 0;
int pass_count = 0;
void test_dst(const char *timezone,
int year,
int month,
int day,
int hour,
int minute,
int second,
int std_offset_hours_expected,
int dst_offset_hours_expected) {
UErrorCode success = U_ZERO_ERROR;
UnicodeString dateReturned, curTZNameEn, curTZNameJp;
UDate dateTime;
int32_t stdOffset, dstOffset;
int std_offset_hours, dst_offset_hours;
TimeZone *tz = TimeZone::createTimeZone(timezone);
curTZNameEn = tz->getDisplayName(Locale::getEnglish(), curTZNameEn);
u_printf("%s-name-english=%S\n",
timezone,
curTZNameEn.getTerminatedBuffer());
curTZNameJp = tz->getDisplayName(Locale::getJapanese(), curTZNameJp);
u_printf("%s-name-japanese=%S\n",
timezone,
curTZNameJp.getTerminatedBuffer());
Calendar *calendar = Calendar::createInstance(success);
calendar->adoptTimeZone(TimeZone::createTimeZone("UTC"));
DateFormat *dt = DateFormat::createDateTimeInstance(
DateFormat::LONG, DateFormat::LONG, Locale("ja", "JP"));
dt->adoptTimeZone(TimeZone::createTimeZone("UTC"));
// Set time in UTC, note that month is from 0-11.
calendar->set(year, month, day, hour, minute, second);
dateTime = calendar->getTime(success);
dateReturned = "";
dateReturned = dt->format(dateTime, dateReturned, success);
printf("current-time-utc-%4d-%d-%d-%d-%d-%d=",
year, month, day, hour, minute, second);
u_printf("%S\n", dateReturned.getTerminatedBuffer());
tz->getOffset(dateTime, true, stdOffset, dstOffset, success);
std_offset_hours = stdOffset/(1000*60*60);
dst_offset_hours = dstOffset/(1000*60*60);
printf("%s-std-offset-%4d-%d-%d-%d-%d-%d=%d\n",
timezone,
year, month, day, hour, minute, second,
std_offset_hours);
if (std_offset_hours != std_offset_hours_expected) {
printf("std_offset_hours=%d, std_offset_hours_expected=%d\n",
std_offset_hours, std_offset_hours_expected);
printf("FAIL\n");
fail_count++;
}
else {
printf("PASS\n");
pass_count++;
}
printf("%s-dst-offset-%4d-%d-%d-%d-%d-%d=%d\n",
timezone,
year, month, day, hour, minute, second,
dst_offset_hours);
if (dst_offset_hours != dst_offset_hours_expected) {
printf("dst_offset_hours=%d, dst_offset_hours_expected=%d\n",
dst_offset_hours, dst_offset_hours_expected);
printf("FAIL\n");
fail_count++;
}
else {
printf("PASS\n");
pass_count++;
}
delete calendar;
delete dt;
delete tz;
}
int main(int argc, char** argv) {
// zdump -c 2019,2020 -v Asia/Gaza
// Asia/Gaza Fri Oct 25 20:59:59 2019 UT = Fri Oct 25 23:59:59 2019 EEST isdst=1 gmtoff=10800
// Asia/Gaza Fri Oct 25 21:00:00 2019 UT = Fri Oct 25 23:00:00 2019 EET isdst=0 gmtoff=7200
// timezone, year, month (0-11), day, hour, minute, second,
// std offset expected, dst offset expected:
test_dst("Asia/Gaza", 2019, 9, 25, 20, 59, 59, 2, 1);
// Why doesnt this work with the exactly correct time?:
test_dst("Asia/Gaza", 2019, 9, 25, 21, 0, 0, 2, 1); // wrong!
test_dst("Asia/Gaza", 2019, 9, 25, 23, 0, 0, 2, 0);
// Asia/Gaza Fri Oct 23 21:59:59 2020 UT = Sat Oct 24 00:59:59 2020 EEST isdst=1 gmtoff=10800
// Asia/Gaza Fri Oct 23 22:00:00 2020 UT = Sat Oct 24 00:00:00 2020 EET isdst=0 gmtoff=7200
test_dst("Asia/Gaza", 2020, 9, 23, 21, 59, 59, 2, 1);
test_dst("Asia/Gaza", 2020, 9, 23, 22, 0, 0, 2, 1); // wrong!
test_dst("Asia/Gaza", 2020, 9, 24, 22, 0, 0, 2, 0);
// Asia/Gaza Thu Oct 28 21:59:59 2021 UT = Fri Oct 29 00:59:59 2021 EEST isdst=1 gmtoff=10800
// Asia/Gaza Thu Oct 28 22:00:00 2021 UT = Fri Oct 29 00:00:00 2021 EET isdst=0 gmtoff=7200
test_dst("Asia/Gaza", 2021, 9, 28, 21, 59, 59, 2, 1);
test_dst("Asia/Gaza", 2021, 9, 28, 22, 0, 0, 2, 1); // wrong!
test_dst("Asia/Gaza", 2021, 9, 29, 21, 59, 59, 2, 0);
test_dst("Asia/Gaza", 2021, 9, 30, 22, 0, 0, 2, 0);
// Print summary and exit with the number of failed test or
// exit with 0 if all tests passed.
printf("Summary: %d tests failed, %d tests passed.\n",
fail_count, pass_count);
if (fail_count != 0) {
printf("FAIL\n");
exit(fail_count);
}
printf("PASS\n");
exit(0);
}