Как генерируются слишком длинные кодировки UTF-8? - PullRequest
1 голос
/ 24 марта 2020

Многие вопросы о переполнении стека о слишком длинных последовательностях UTF-8 связаны с их обнаружением и предотвращением. У меня вопрос, откуда эти последовательности? Как они генерируются? Я просмотрел статью в Википедии о кодировке UTF-8 и несколько других вопросов о переполнении стека, но не могу понять, как их сгенерировать.

1 Ответ

1 голос
/ 25 марта 2020

Согласно RF C 3629 , символы Unicode от U + 0080 до U + 07FF используют 2-байтовую кодировку UTF-8, которая кодирует до 11 битов, например:

U + 0080 = 00010000000 bin (начальные нули для 11 бит)
UTF-8 2-байтовый шаблон кодирования = 110 xxxxx 10 xxxxxx bin

Распределение первых 5 битов в первом байте и последних 6 битов во втором байте:

110 00010 10 000000 bin = C2 80 hex

Вы делаете слишком длинную кодировку UTF-8, например, используя более длинное кодирование в кодовой точке Unicode ниже допустимого диапазона, например, U + 007F находится в 1-байтовом диапазоне кодирования и должно быть закодировано как 7F hex , но оно может быть чрезмерно закодировано как:

U + 007F = 01111111 bin

2 байта: 110 00001 10 111111 bin = C1 BF hex
3 байта: 1110 0000 10 000001 10 111111 bin = E0 81 BF hex
4 байта: 11110 000 10 000000 10 000001 10 111111 bin = F0 80 81 BF hex

Эти слишком длинные кодировки являются незаконными. Всегда следует использовать самую короткую кодировку.

Вот пример определения языка Python:

>>> b'\xc1\xbf'.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc1 in position 0: invalid start byte
>>> b'\xe0\x81\xbf'.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 0: invalid continuation byte
>>> b'\xf0\x80\x81\xbf'.decode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf0 in position 0: invalid continuation byte
>>> b'\x7f'.decode('utf8')
'\x7f'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...