Index: source/common/rbbidata.cpp |
diff --git a/source/common/rbbidata.cpp b/source/common/rbbidata.cpp |
index 09d47964e61274bee6904925dfbd5766ebee6e0b..271553a89c19b3449e3bb7d5d50c32ca5d669cbc 100644 |
--- a/source/common/rbbidata.cpp |
+++ b/source/common/rbbidata.cpp |
@@ -1,6 +1,6 @@ |
/* |
*************************************************************************** |
-* Copyright (C) 1999-2010 International Business Machines Corporation * |
+* Copyright (C) 1999-2014 International Business Machines Corporation * |
* and others. All rights reserved. * |
*************************************************************************** |
*/ |
@@ -46,20 +46,39 @@ U_NAMESPACE_BEGIN |
// |
//----------------------------------------------------------------------------- |
RBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, UErrorCode &status) { |
+ init0(); |
init(data, status); |
} |
RBBIDataWrapper::RBBIDataWrapper(const RBBIDataHeader *data, enum EDontAdopt, UErrorCode &status) { |
+ init0(); |
init(data, status); |
fDontFreeData = TRUE; |
} |
RBBIDataWrapper::RBBIDataWrapper(UDataMemory* udm, UErrorCode &status) { |
- const RBBIDataHeader *d = (const RBBIDataHeader *) |
- // ((char *)&(udm->pHeader->info) + udm->pHeader->info.size); |
- // taking into consideration the padding added in by udata_write |
- ((char *)(udm->pHeader) + udm->pHeader->dataHeader.headerSize); |
- init(d, status); |
+ init0(); |
+ if (U_FAILURE(status)) { |
+ return; |
+ } |
+ const DataHeader *dh = udm->pHeader; |
+ int32_t headerSize = dh->dataHeader.headerSize; |
+ if ( !(headerSize >= 20 && |
+ dh->info.isBigEndian == U_IS_BIG_ENDIAN && |
+ dh->info.charsetFamily == U_CHARSET_FAMILY && |
+ dh->info.dataFormat[0] == 0x42 && // dataFormat="Brk " |
+ dh->info.dataFormat[1] == 0x72 && |
+ dh->info.dataFormat[2] == 0x6b && |
+ dh->info.dataFormat[3] == 0x20) |
+ // Note: info.fFormatVersion is duplicated in the RBBIDataHeader, and is |
+ // validated when checking that. |
+ ) { |
+ status = U_INVALID_FORMAT_ERROR; |
+ return; |
+ } |
+ const char *dataAsBytes = reinterpret_cast<const char *>(dh); |
+ const RBBIDataHeader *rbbidh = reinterpret_cast<const RBBIDataHeader *>(dataAsBytes + headerSize); |
+ init(rbbidh, status); |
fUDataMem = udm; |
} |
@@ -69,6 +88,19 @@ RBBIDataWrapper::RBBIDataWrapper(UDataMemory* udm, UErrorCode &status) { |
// constructors. |
// |
//----------------------------------------------------------------------------- |
+void RBBIDataWrapper::init0() { |
+ fHeader = NULL; |
+ fForwardTable = NULL; |
+ fReverseTable = NULL; |
+ fSafeFwdTable = NULL; |
+ fSafeRevTable = NULL; |
+ fRuleSource = NULL; |
+ fRuleStatusTable = NULL; |
+ fUDataMem = NULL; |
+ fRefCount = 0; |
+ fDontFreeData = TRUE; |
+} |
+ |
void RBBIDataWrapper::init(const RBBIDataHeader *data, UErrorCode &status) { |
if (U_FAILURE(status)) { |
return; |
@@ -84,10 +116,6 @@ void RBBIDataWrapper::init(const RBBIDataHeader *data, UErrorCode &status) { |
// an int32_t field, rather than an array of 4 bytes. |
fDontFreeData = FALSE; |
- fUDataMem = NULL; |
- fReverseTable = NULL; |
- fSafeFwdTable = NULL; |
- fSafeRevTable = NULL; |
if (data->fFTableLen != 0) { |
fForwardTable = (RBBIStateTable *)((char *)data + fHeader->fFTable); |
} |