ICU-10561 ZoneMeta methods must check for bogus input strings

X-SVN-Rev: 34873
This commit is contained in:
Markus Scherer 2014-01-10 23:14:14 +00:00
parent 9dd53d288d
commit 90b6b64024
8 changed files with 59 additions and 24 deletions

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2013, International Business Machines Corporation and
* Copyright (C) 1997-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
@ -1293,6 +1293,8 @@ TimeZone::getCustomID(const UnicodeString& id, UnicodeString& normalized, UError
int32_t sign, hour, min, sec;
if (parseCustomID(id, sign, hour, min, sec)) {
formatCustomID(hour, min, sec, (sign < 0), normalized);
} else {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
return normalized;
}
@ -1538,6 +1540,11 @@ TimeZone::getWindowsID(const UnicodeString& id, UnicodeString& winid, UErrorCode
getCanonicalID(id, canonicalID, isSystemID, status);
if (U_FAILURE(status) || !isSystemID) {
// mapping data is only applicable to tz database IDs
if (status == U_ILLEGAL_ARGUMENT_ERROR) {
// getWindowsID() sets an empty string where
// getCanonicalID() sets a U_ILLEGAL_ARGUMENT_ERROR.
status = U_ZERO_ERROR;
}
return winid;
}

View file

@ -1,5 +1,5 @@
/*************************************************************************
* Copyright (c) 1997-2013, International Business Machines Corporation
* Copyright (c) 1997-2014, International Business Machines Corporation
* and others. All Rights Reserved.
**************************************************************************
*
@ -330,7 +330,7 @@ public:
* @param id The input time zone ID to be canonicalized.
* @param canonicalID Receives the canonical system time zone ID
* or the custom time zone ID in normalized format.
* @param status Recevies the status. When the given time zone ID
* @param status Receives the status. When the given time zone ID
* is neither a known system time zone ID nor a
* valid custom time zone ID, U_ILLEGAL_ARGUMENT_ERROR
* is set.
@ -348,7 +348,7 @@ public:
* or the custom time zone ID in normalized format.
* @param isSystemID Receives if the given ID is a known system
* time zone ID.
* @param status Recevies the status. When the given time zone ID
* @param status Receives the status. When the given time zone ID
* is neither a known system time zone ID nor a
* valid custom time zone ID, U_ILLEGAL_ARGUMENT_ERROR
* is set.

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 2011-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2011-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#ifndef __TZFMT_H
@ -302,7 +302,7 @@ public:
/**
* Creates an instance of <code>TimeZoneFormat</code> for the given locale.
* @param locale The locale.
* @param status Recevies the status.
* @param status Receives the status.
* @return An instance of <code>TimeZoneFormat</code> for the given locale,
* owned by the caller.
* @stable ICU 50

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
* Copyright (C) 2011-2013, International Business Machines Corporation and *
* others. All Rights Reserved. *
* Copyright (C) 2011-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
#ifndef __TZNAMES_H
@ -163,7 +163,7 @@ public:
* Returns an instance of <code>TimeZoneDisplayNames</code> for the specified locale.
*
* @param locale The locale.
* @param status Recevies the status.
* @param status Receives the status.
* @return An instance of <code>TimeZoneDisplayNames</code>
* @stable ICU 50
*/
@ -171,7 +171,7 @@ public:
/**
* Returns an enumeration of all available meta zone IDs.
* @param status Recevies the status.
* @param status Receives the status.
* @return an enumeration object, owned by the caller.
* @stable ICU 50
*/
@ -180,7 +180,7 @@ public:
/**
* Returns an enumeration of all available meta zone IDs used by the given time zone.
* @param tzID The canoical tiem zone ID.
* @param status Recevies the status.
* @param status Receives the status.
* @return an enumeration object, owned by the caller.
* @stable ICU 50
*/

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1996-2013, International Business Machines Corporation and
* Copyright (C) 1996-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@ -1289,7 +1289,7 @@ ucal_getTZDataVersion(UErrorCode* status);
* @param resultCapacity The capacity of the result buffer.
* @param isSystemID Receives if the given ID is a known system
* timezone ID.
* @param status Recevies the status. When the given timezone ID
* @param status Receives the status. When the given timezone ID
* is neither a known system time zone ID nor a
* valid custom timezone ID, U_ILLEGAL_ARGUMENT_ERROR
* is set.

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2007-2013, International Business Machines Corporation and
* Copyright (C) 2007-2014, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
@ -27,6 +27,8 @@
#include "uhash.h"
#include "olsontz.h"
#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
static UMutex gZoneMetaLock = U_MUTEX_INITIALIZER;
// CLDR Canonical ID mapping table
@ -235,8 +237,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
return NULL;
}
int32_t len = tzid.length();
if (len > ZID_KEY_MAX) {
if (tzid.isBogus() || tzid.length() > ZID_KEY_MAX) {
status = U_ILLEGAL_ARGUMENT_ERROR;
return NULL;
}
@ -268,10 +269,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
// If not, resolve CLDR canonical ID with resource data
UBool isInputCanonical = FALSE;
char id[ZID_KEY_MAX + 1];
const UChar* idChars = tzid.getBuffer();
u_UCharsToChars(idChars,id,len);
id[len] = (char) 0; // Make sure it is null terminated.
tzid.extract(0, 0x7fffffff, id, LENGTHOF(id), US_INV);
// replace '/' with ':'
char *p = id;
@ -309,7 +307,7 @@ ZoneMeta::getCanonicalCLDRID(const UnicodeString &tzid, UErrorCode& status) {
if (derefer == NULL) {
status = U_ILLEGAL_ARGUMENT_ERROR;
} else {
len = u_strlen(derefer);
int32_t len = u_strlen(derefer);
u_UCharsToChars(derefer,id,len);
id[len] = (char) 0; // Make sure it is null terminated.
@ -717,7 +715,7 @@ ZoneMeta::getZoneIdByMetazone(const UnicodeString &mzid, const UnicodeString &re
char keyBuf[ZID_KEY_MAX + 1];
int32_t keyLen = 0;
if (mzid.length() > ZID_KEY_MAX) {
if (mzid.isBogus() || mzid.length() > ZID_KEY_MAX) {
result.setToBogus();
return result;
}

View file

@ -66,6 +66,7 @@ void TimeZoneTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
TESTCASE_AUTO(TestAliasedNames);
TESTCASE_AUTO(TestFractionalDST);
TESTCASE_AUTO(TestFebruary);
TESTCASE_AUTO(TestCanonicalIDAPI);
TESTCASE_AUTO(TestCanonicalID);
TESTCASE_AUTO(TestDisplayNamesMeta);
TESTCASE_AUTO(TestGetRegion);
@ -1938,6 +1939,34 @@ void TimeZoneTest::TestFebruary() {
}
}
}
void TimeZoneTest::TestCanonicalIDAPI() {
// Bogus input string.
UnicodeString bogus;
bogus.setToBogus();
UnicodeString canonicalID;
UErrorCode ec = U_ZERO_ERROR;
UnicodeString *pResult = &TimeZone::getCanonicalID(bogus, canonicalID, ec);
assertEquals("TimeZone::getCanonicalID(bogus) should fail", U_ILLEGAL_ARGUMENT_ERROR, ec);
assertTrue("TimeZone::getCanonicalID(bogus) should return the dest string", pResult == &canonicalID);
// U_FAILURE on input.
UnicodeString berlin("Europe/Berlin");
ec = U_MEMORY_ALLOCATION_ERROR;
pResult = &TimeZone::getCanonicalID(berlin, canonicalID, ec);
assertEquals("TimeZone::getCanonicalID(failure) should fail", U_MEMORY_ALLOCATION_ERROR, ec);
assertTrue("TimeZone::getCanonicalID(failure) should return the dest string", pResult == &canonicalID);
// Valid input should un-bogus the dest string.
canonicalID.setToBogus();
ec = U_ZERO_ERROR;
pResult = &TimeZone::getCanonicalID(berlin, canonicalID, ec);
assertSuccess("TimeZone::getCanonicalID(bogus dest) should succeed", ec);
assertTrue("TimeZone::getCanonicalID(bogus dest) should return the dest string", pResult == &canonicalID);
assertFalse("TimeZone::getCanonicalID(bogus dest) should un-bogus the dest string", canonicalID.isBogus());
assertEquals("TimeZone::getCanonicalID(bogus dest) unexpected result", canonicalID, berlin);
}
void TimeZoneTest::TestCanonicalID() {
// Some canonical IDs in CLDR are defined as "Link"

View file

@ -1,6 +1,6 @@
/********************************************************************
* Copyright (c) 1997-2013, International Business Machines
* Copyright (c) 1997-2014, International Business Machines
* Corporation and others. All Rights Reserved.
********************************************************************/
@ -90,6 +90,7 @@ public:
void TestFebruary(void);
void TestCanonicalIDAPI();
void TestCanonicalID(void);
virtual void TestDisplayNamesMeta();