| 520 | asnativebytes('not a number', buffer, 0, -1) |
| 521 | |
| 522 | def test_long_asnativebytes_fuzz(self): |
| 523 | import math |
| 524 | from random import Random |
| 525 | from _testcapi import ( |
| 526 | pylong_asnativebytes as asnativebytes, |
| 527 | SIZE_MAX, |
| 528 | ) |
| 529 | |
| 530 | # Abbreviate sizeof(Py_ssize_t) to SZ because we use it a lot |
| 531 | SZ = int(math.ceil(math.log(SIZE_MAX + 1) / math.log(2)) / 8) |
| 532 | |
| 533 | rng = Random() |
| 534 | # Allocate bigger buffer than actual values are going to be |
| 535 | buffer = bytearray(260) |
| 536 | |
| 537 | for _ in range(1000): |
| 538 | n = rng.randrange(1, 256) |
| 539 | bytes_be = bytes([ |
| 540 | # Ensure the most significant byte is nonzero |
| 541 | rng.randrange(1, 256), |
| 542 | *[rng.randrange(256) for _ in range(n - 1)] |
| 543 | ]) |
| 544 | bytes_le = bytes_be[::-1] |
| 545 | v = int.from_bytes(bytes_le, 'little') |
| 546 | |
| 547 | expect_1 = expect_2 = (SZ, n) |
| 548 | if bytes_be[0] & 0x80: |
| 549 | # All values are positive, so if MSB is set, expect extra bit |
| 550 | # when we request the size or have a large enough buffer |
| 551 | expect_1 = (SZ, n + 1) |
| 552 | # When passing Py_ASNATIVEBYTES_UNSIGNED_BUFFER, we expect the |
| 553 | # return to be exactly the right size. |
| 554 | expect_2 = (n,) |
| 555 | |
| 556 | try: |
| 557 | actual = asnativebytes(v, buffer, 0, -1) |
| 558 | self.assertIn(actual, expect_1) |
| 559 | |
| 560 | actual = asnativebytes(v, buffer, len(buffer), 0) |
| 561 | self.assertIn(actual, expect_1) |
| 562 | self.assertEqual(bytes_be, buffer[-n:]) |
| 563 | |
| 564 | actual = asnativebytes(v, buffer, len(buffer), 1) |
| 565 | self.assertIn(actual, expect_1) |
| 566 | self.assertEqual(bytes_le, buffer[:n]) |
| 567 | |
| 568 | actual = asnativebytes(v, buffer, n, 4) |
| 569 | self.assertIn(actual, expect_2, bytes_be.hex()) |
| 570 | actual = asnativebytes(v, buffer, n, 5) |
| 571 | self.assertIn(actual, expect_2, bytes_be.hex()) |
| 572 | except AssertionError as ex: |
| 573 | value_hex = ''.join(reversed([ |
| 574 | f'{b:02X}{"" if i % 8 else "_"}' |
| 575 | for i, b in enumerate(bytes_le, start=1) |
| 576 | ])).strip('_') |
| 577 | if support.verbose: |
| 578 | print() |
| 579 | print(n, 'bytes') |