Merge pull request #33021 from DevTeamBK/Issue135

Fix null pointer dereference in low cardinality data
This commit is contained in:
Nikolay Degterinsky 2021-12-22 17:03:23 +03:00 committed by GitHub
commit e1a58d0889
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 0 deletions

View File

@ -636,6 +636,9 @@ void SerializationLowCardinality::deserializeBinaryBulkWithMultipleStreams(
if (!low_cardinality_state->index_type.need_global_dictionary) if (!low_cardinality_state->index_type.need_global_dictionary)
{ {
if(additional_keys == nullptr)
throw Exception("No additional keys found.", ErrorCodes::INCORRECT_DATA);
ColumnPtr keys_column = additional_keys; ColumnPtr keys_column = additional_keys;
if (low_cardinality_state->null_map) if (low_cardinality_state->null_map)
keys_column = ColumnNullable::create(additional_keys, low_cardinality_state->null_map); keys_column = ColumnNullable::create(additional_keys, low_cardinality_state->null_map);
@ -662,6 +665,9 @@ void SerializationLowCardinality::deserializeBinaryBulkWithMultipleStreams(
if (!maps.additional_keys_map->empty()) if (!maps.additional_keys_map->empty())
{ {
if(additional_keys == nullptr)
throw Exception("No additional keys found.", ErrorCodes::INCORRECT_DATA);
auto used_add_keys = additional_keys->index(*maps.additional_keys_map, 0); auto used_add_keys = additional_keys->index(*maps.additional_keys_map, 0);
if (dictionary_type->isNullable()) if (dictionary_type->isNullable())

View File

@ -302,11 +302,44 @@ def insertLowCardinalityRowWithIncorrectDictType():
print(readException(s)) print(readException(s))
s.close() s.close()
def insertLowCardinalityRowWithIncorrectAdditionalKeys():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(30)
s.connect((CLICKHOUSE_HOST, CLICKHOUSE_PORT))
sendHello(s)
receiveHello(s)
sendQuery(s, 'insert into {}.tab format TSV'.format(CLICKHOUSE_DATABASE))
# external tables
sendEmptyBlock(s)
readHeader(s)
# Data
ba = bytearray()
writeVarUInt(2, ba) # Data
writeStringBinary('', ba)
serializeBlockInfo(ba)
writeVarUInt(1, ba) # rows
writeVarUInt(1, ba) # columns
writeStringBinary('x', ba)
writeStringBinary('LowCardinality(String)', ba)
ba.extend([1] + [0] * 7) # SharedDictionariesWithAdditionalKeys
ba.extend([3, 0] + [0] * 6) # indexes type: UInt64 [3], with NO additional keys [0]
ba.extend([1] + [0] * 7) # num_keys in dict
writeStringBinary('hello', ba) # key
ba.extend([1] + [0] * 7) # num_indexes
ba.extend([0] * 8) # UInt64 index (0 for 'hello')
s.sendall(ba)
assertPacket(readVarUInt(s), 2)
print(readException(s))
s.close()
def main(): def main():
insertValidLowCardinalityRow() insertValidLowCardinalityRow()
insertLowCardinalityRowWithIndexOverflow() insertLowCardinalityRowWithIndexOverflow()
insertLowCardinalityRowWithIncorrectDictType() insertLowCardinalityRowWithIncorrectDictType()
insertLowCardinalityRowWithIncorrectAdditionalKeys()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -6,3 +6,6 @@ code 117: Index for LowCardinality is out of range. Dictionary size is 1, but f
Rows 0 Columns 1 Rows 0 Columns 1
Column x type LowCardinality(String) Column x type LowCardinality(String)
code 117: LowCardinality indexes serialization type for Native format cannot use global dictionary code 117: LowCardinality indexes serialization type for Native format cannot use global dictionary
Rows 0 Columns 1
Column x type LowCardinality(String)
code 117: No additional keys found.