mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
Improve _ChunkedValue's handling of split chunks with unexpected whitespace
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
## v1.?.? - 2024-??-?? - ???
|
||||
|
||||
* Fix CAA rdata parsing to allow values with tags
|
||||
* Improve TXT (and SPF) record handling of unexpected whitespace
|
||||
before/after/in-between quotes.
|
||||
|
||||
## v1.7.0 - 2024-04-29 - All the knobs and dials
|
||||
|
||||
|
@ -34,6 +34,7 @@ class _ChunkedValuesMixin(ValuesMixin):
|
||||
|
||||
class _ChunkedValue(str):
|
||||
_unescaped_semicolon_re = re.compile(r'\w;')
|
||||
_chunk_sep_re = re.compile(r'"\s+"')
|
||||
|
||||
@classmethod
|
||||
def parse_rdata_text(cls, value):
|
||||
@ -62,9 +63,11 @@ class _ChunkedValue(str):
|
||||
def process(cls, values):
|
||||
ret = []
|
||||
for v in values:
|
||||
# remove leading/trailing whitespace
|
||||
v = v.strip()
|
||||
if v and v[0] == '"':
|
||||
v = v[1:-1]
|
||||
ret.append(cls(v.replace('" "', '')))
|
||||
ret.append(cls(cls._chunk_sep_re.sub('', v)))
|
||||
return ret
|
||||
|
||||
@property
|
||||
|
@ -67,3 +67,99 @@ class TestChunkedValue(TestCase):
|
||||
['non ASCII character in "Déjà vu"'],
|
||||
_ChunkedValue.validate('Déjà vu', 'TXT'),
|
||||
)
|
||||
|
||||
def test_large_values(self):
|
||||
# There is additional testing in TXT
|
||||
|
||||
# "standard" format quoted and split value
|
||||
value = (
|
||||
'"Lorem ipsum dolor sit amet, consectetur '
|
||||
'adipiscing elit, sed do eiusmod tempor incididunt ut '
|
||||
'labore et dolore magna aliqua. Ut enim ad minim veniam, '
|
||||
'quis nostrud exercitation ullamco laboris nisi ut aliquip '
|
||||
'ex" " ea commodo consequat. Duis aute irure dolor in '
|
||||
'reprehenderit in voluptate velit esse cillum dolore eu '
|
||||
'fugiat nulla pariatur. Excepteur sint occaecat cupidatat '
|
||||
'non proident, sunt in culpa qui officia deserunt mollit '
|
||||
'anim id est laborum."'
|
||||
)
|
||||
chunked = _ChunkedValue.process([value])
|
||||
self.assertEqual(1, len(chunked))
|
||||
chunked = chunked[0]
|
||||
self.assertIsInstance(chunked, _ChunkedValue)
|
||||
dechunked_value = (
|
||||
'Lorem ipsum dolor sit amet, consectetur '
|
||||
'adipiscing elit, sed do eiusmod tempor incididunt ut '
|
||||
'labore et dolore magna aliqua. Ut enim ad minim veniam, '
|
||||
'quis nostrud exercitation ullamco laboris nisi ut aliquip '
|
||||
'ex ea commodo consequat. Duis aute irure dolor in '
|
||||
'reprehenderit in voluptate velit esse cillum dolore eu '
|
||||
'fugiat nulla pariatur. Excepteur sint occaecat cupidatat '
|
||||
'non proident, sunt in culpa qui officia deserunt mollit '
|
||||
'anim id est laborum.'
|
||||
)
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
|
||||
# already dechunked, noop
|
||||
chunked = _ChunkedValue.process([dechunked_value])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
|
||||
# leading whitespace
|
||||
chunked = _ChunkedValue.process([f' {value}'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f' {value}'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f'\t{value}'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f'\t\t{value}'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f' \t{value}'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
|
||||
# trailing whitespace
|
||||
chunked = _ChunkedValue.process([f'{value} '])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f'{value} '])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f'{value}\t'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f'{value}\t\t'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f'{value} \t'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
|
||||
# both
|
||||
chunked = _ChunkedValue.process([f' {value} '])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f'\t{value} '])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
chunked = _ChunkedValue.process([f' {value}\t'])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
|
||||
# variations of whitepsace in the chunk seperator
|
||||
multi = value.replace('" "', '" "')
|
||||
chunked = _ChunkedValue.process([multi])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
multi = value.replace('" "', '"\t"')
|
||||
chunked = _ChunkedValue.process([multi])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
multi = value.replace('" "', '"\t\t"')
|
||||
chunked = _ChunkedValue.process([multi])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
multi = value.replace('" "', '" \t"')
|
||||
chunked = _ChunkedValue.process([multi])[0]
|
||||
self.assertEqual(dechunked_value, chunked)
|
||||
|
||||
# ~real world test case
|
||||
values = [
|
||||
'before',
|
||||
' "v=DKIM1\\; h=sha256\\; k=rsa\\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx78E7PtJvr8vpoNgHdIAe+llFKoy8WuTXDd6Z5mm3D4AUva9MBt5fFetxg/kcRy3KMDnMw6kDybwbpS/oPw1ylk6DL1xit7Cr5xeYYSWKukxXURAlHwT2K72oUsFKRUvN1X9lVysAeo+H8H/22Z9fJ0P30sOuRIRqCaiz+OiUYicxy4x" "rpfH2s9a+o3yRwX3zhlp8GjRmmmyK5mf7CkQTCfjnKVsYtB7mabXXmClH9tlcymnBMoN9PeXxaS5JRRysVV8RBCC9/wmfp9y//cck8nvE/MavFpSUHvv+TfTTdVKDlsXPjKX8iZQv0nO3xhspgkqFquKjydiR8nf4meHhwIDAQAB" ',
|
||||
'z after',
|
||||
]
|
||||
chunked = _ChunkedValue.process(values)
|
||||
expected = [
|
||||
'before',
|
||||
'v=DKIM1\\; h=sha256\\; k=rsa\\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx78E7PtJvr8vpoNgHdIAe+llFKoy8WuTXDd6Z5mm3D4AUva9MBt5fFetxg/kcRy3KMDnMw6kDybwbpS/oPw1ylk6DL1xit7Cr5xeYYSWKukxXURAlHwT2K72oUsFKRUvN1X9lVysAeo+H8H/22Z9fJ0P30sOuRIRqCaiz+OiUYicxy4xrpfH2s9a+o3yRwX3zhlp8GjRmmmyK5mf7CkQTCfjnKVsYtB7mabXXmClH9tlcymnBMoN9PeXxaS5JRRysVV8RBCC9/wmfp9y//cck8nvE/MavFpSUHvv+TfTTdVKDlsXPjKX8iZQv0nO3xhspgkqFquKjydiR8nf4meHhwIDAQAB',
|
||||
'z after',
|
||||
]
|
||||
self.assertEqual(expected, chunked)
|
||||
|
Reference in New Issue
Block a user