- data->scripts = reinterpret_cast<const uint16_t *>(inBytes + offset);
- data->scriptsLength = length / 2;
+ const uint16_t *scripts = reinterpret_cast<const uint16_t *>(inBytes + offset);
+ int32_t scriptsLength = length / 2;
+ data->numScripts = scripts[0];
+ // There must be enough entries for both arrays, including more than two range starts.
+ data->scriptStartsLength = scriptsLength - (1 + data->numScripts + 16);
+ if(data->scriptStartsLength <= 2 ||
+ CollationData::MAX_NUM_SCRIPT_RANGES < data->scriptStartsLength) {
+ errorCode = U_INVALID_FORMAT_ERROR;
+ return;
+ }
+ data->scriptsIndex = scripts + 1;
+ data->scriptStarts = scripts + 1 + data->numScripts + 16;
+ if(!(data->scriptStarts[0] == 0 &&
+ data->scriptStarts[1] == ((Collation::MERGE_SEPARATOR_BYTE + 1) << 8) &&
+ data->scriptStarts[data->scriptStartsLength - 1] ==
+ (Collation::TRAIL_WEIGHT_BYTE << 8))) {
+ errorCode = U_INVALID_FORMAT_ERROR;
+ return;
+ }