|
21 | 21 |
|
22 | 22 | """Tests REST events for /profile paths.""" |
23 | 23 |
|
| 24 | +import logging |
24 | 25 | import urllib.parse |
25 | 26 | from http import HTTPStatus |
26 | 27 | from typing import Any, Dict, Optional |
@@ -648,87 +649,96 @@ def test_set_custom_field_profile_too_long(self) -> None: |
648 | 649 | """ |
649 | 650 | Attempts to set a custom field that would push the overall profile too large. |
650 | 651 | """ |
651 | | - # Get right to the boundary: |
652 | | - # len("displayname") + len("owner") + 5 = 21 for the displayname |
653 | | - # 1 + 65498 + 5 for key "a" = 65504 |
654 | | - # 2 braces, 1 comma |
655 | | - # 3 + 21 + 65498 = 65522 < 65536. |
656 | | - key = "a" |
657 | | - channel = self.make_request( |
658 | | - "PUT", |
659 | | - f"/_matrix/client/v3/profile/{self.owner}/{key}", |
660 | | - content={key: "a" * 65498}, |
661 | | - access_token=self.owner_tok, |
662 | | - ) |
663 | | - self.assertEqual(channel.code, 200, channel.result) |
664 | | - |
665 | | - # Get the entire profile. |
666 | | - channel = self.make_request( |
667 | | - "GET", |
668 | | - f"/_matrix/client/v3/profile/{self.owner}", |
669 | | - access_token=self.owner_tok, |
670 | | - ) |
671 | | - self.assertEqual(channel.code, 200, channel.result) |
672 | | - canonical_json = encode_canonical_json(channel.json_body) |
673 | | - # 6 is the minimum bytes to store a value: 4 quotes, 1 colon, 1 comma, an empty key. |
674 | | - # Be one below that so we can prove we're at the boundary. |
675 | | - self.assertEqual(len(canonical_json), MAX_PROFILE_SIZE - 8) |
676 | | - |
677 | | - # Postgres stores JSONB with whitespace, while SQLite doesn't. |
678 | | - if USE_POSTGRES_FOR_TESTS: |
679 | | - ADDITIONAL_CHARS = 0 |
680 | | - else: |
681 | | - ADDITIONAL_CHARS = 1 |
| 652 | + # Because we emit huge SQL log lines and trial sometimes crashes on these, |
| 653 | + # disable SQL logging for this test |
| 654 | + # ref: https://github.com/twisted/twisted/issues/12482 |
| 655 | + sql_logger = logging.getLogger("synapse.storage.SQL") |
| 656 | + sql_logger_was_disabled = sql_logger.disabled |
| 657 | + sql_logger.disabled = True |
| 658 | + try: |
| 659 | + # Get right to the boundary: |
| 660 | + # len("displayname") + len("owner") + 5 = 21 for the displayname |
| 661 | + # 1 + 65498 + 5 for key "a" = 65504 |
| 662 | + # 2 braces, 1 comma |
| 663 | + # 3 + 21 + 65498 = 65522 < 65536. |
| 664 | + key = "a" |
| 665 | + channel = self.make_request( |
| 666 | + "PUT", |
| 667 | + f"/_matrix/client/v3/profile/{self.owner}/{key}", |
| 668 | + content={key: "a" * 65498}, |
| 669 | + access_token=self.owner_tok, |
| 670 | + ) |
| 671 | + self.assertEqual(channel.code, 200, channel.result) |
682 | 672 |
|
683 | | - # The next one should fail, note the value has a (JSON) length of 2. |
684 | | - key = "b" |
685 | | - channel = self.make_request( |
686 | | - "PUT", |
687 | | - f"/_matrix/client/v3/profile/{self.owner}/{key}", |
688 | | - content={key: "1" + "a" * ADDITIONAL_CHARS}, |
689 | | - access_token=self.owner_tok, |
690 | | - ) |
691 | | - self.assertEqual(channel.code, 400, channel.result) |
692 | | - self.assertEqual(channel.json_body["errcode"], Codes.PROFILE_TOO_LARGE) |
| 673 | + # Get the entire profile. |
| 674 | + channel = self.make_request( |
| 675 | + "GET", |
| 676 | + f"/_matrix/client/v3/profile/{self.owner}", |
| 677 | + access_token=self.owner_tok, |
| 678 | + ) |
| 679 | + self.assertEqual(channel.code, 200, channel.result) |
| 680 | + canonical_json = encode_canonical_json(channel.json_body) |
| 681 | + # 6 is the minimum bytes to store a value: 4 quotes, 1 colon, 1 comma, an empty key. |
| 682 | + # Be one below that so we can prove we're at the boundary. |
| 683 | + self.assertEqual(len(canonical_json), MAX_PROFILE_SIZE - 8) |
| 684 | + |
| 685 | + # Postgres stores JSONB with whitespace, while SQLite doesn't. |
| 686 | + if USE_POSTGRES_FOR_TESTS: |
| 687 | + ADDITIONAL_CHARS = 0 |
| 688 | + else: |
| 689 | + ADDITIONAL_CHARS = 1 |
| 690 | + |
| 691 | + # The next one should fail, note the value has a (JSON) length of 2. |
| 692 | + key = "b" |
| 693 | + channel = self.make_request( |
| 694 | + "PUT", |
| 695 | + f"/_matrix/client/v3/profile/{self.owner}/{key}", |
| 696 | + content={key: "1" + "a" * ADDITIONAL_CHARS}, |
| 697 | + access_token=self.owner_tok, |
| 698 | + ) |
| 699 | + self.assertEqual(channel.code, 400, channel.result) |
| 700 | + self.assertEqual(channel.json_body["errcode"], Codes.PROFILE_TOO_LARGE) |
693 | 701 |
|
694 | | - # Setting an avatar or (longer) display name should not work. |
695 | | - channel = self.make_request( |
696 | | - "PUT", |
697 | | - f"/profile/{self.owner}/displayname", |
698 | | - content={"displayname": "owner12345678" + "a" * ADDITIONAL_CHARS}, |
699 | | - access_token=self.owner_tok, |
700 | | - ) |
701 | | - self.assertEqual(channel.code, 400, channel.result) |
702 | | - self.assertEqual(channel.json_body["errcode"], Codes.PROFILE_TOO_LARGE) |
| 702 | + # Setting an avatar or (longer) display name should not work. |
| 703 | + channel = self.make_request( |
| 704 | + "PUT", |
| 705 | + f"/profile/{self.owner}/displayname", |
| 706 | + content={"displayname": "owner12345678" + "a" * ADDITIONAL_CHARS}, |
| 707 | + access_token=self.owner_tok, |
| 708 | + ) |
| 709 | + self.assertEqual(channel.code, 400, channel.result) |
| 710 | + self.assertEqual(channel.json_body["errcode"], Codes.PROFILE_TOO_LARGE) |
703 | 711 |
|
704 | | - channel = self.make_request( |
705 | | - "PUT", |
706 | | - f"/profile/{self.owner}/avatar_url", |
707 | | - content={"avatar_url": "mxc://foo/bar"}, |
708 | | - access_token=self.owner_tok, |
709 | | - ) |
710 | | - self.assertEqual(channel.code, 400, channel.result) |
711 | | - self.assertEqual(channel.json_body["errcode"], Codes.PROFILE_TOO_LARGE) |
| 712 | + channel = self.make_request( |
| 713 | + "PUT", |
| 714 | + f"/profile/{self.owner}/avatar_url", |
| 715 | + content={"avatar_url": "mxc://foo/bar"}, |
| 716 | + access_token=self.owner_tok, |
| 717 | + ) |
| 718 | + self.assertEqual(channel.code, 400, channel.result) |
| 719 | + self.assertEqual(channel.json_body["errcode"], Codes.PROFILE_TOO_LARGE) |
712 | 720 |
|
713 | | - # Removing a single byte should work. |
714 | | - key = "b" |
715 | | - channel = self.make_request( |
716 | | - "PUT", |
717 | | - f"/_matrix/client/v3/profile/{self.owner}/{key}", |
718 | | - content={key: "" + "a" * ADDITIONAL_CHARS}, |
719 | | - access_token=self.owner_tok, |
720 | | - ) |
721 | | - self.assertEqual(channel.code, 200, channel.result) |
| 721 | + # Removing a single byte should work. |
| 722 | + key = "b" |
| 723 | + channel = self.make_request( |
| 724 | + "PUT", |
| 725 | + f"/_matrix/client/v3/profile/{self.owner}/{key}", |
| 726 | + content={key: "" + "a" * ADDITIONAL_CHARS}, |
| 727 | + access_token=self.owner_tok, |
| 728 | + ) |
| 729 | + self.assertEqual(channel.code, 200, channel.result) |
722 | 730 |
|
723 | | - # Finally, setting a field that already exists to a value that is <= in length should work. |
724 | | - key = "a" |
725 | | - channel = self.make_request( |
726 | | - "PUT", |
727 | | - f"/_matrix/client/v3/profile/{self.owner}/{key}", |
728 | | - content={key: ""}, |
729 | | - access_token=self.owner_tok, |
730 | | - ) |
731 | | - self.assertEqual(channel.code, 200, channel.result) |
| 731 | + # Finally, setting a field that already exists to a value that is <= in length should work. |
| 732 | + key = "a" |
| 733 | + channel = self.make_request( |
| 734 | + "PUT", |
| 735 | + f"/_matrix/client/v3/profile/{self.owner}/{key}", |
| 736 | + content={key: ""}, |
| 737 | + access_token=self.owner_tok, |
| 738 | + ) |
| 739 | + self.assertEqual(channel.code, 200, channel.result) |
| 740 | + finally: |
| 741 | + sql_logger.disabled = sql_logger_was_disabled |
732 | 742 |
|
733 | 743 | def test_set_custom_field_displayname(self) -> None: |
734 | 744 | channel = self.make_request( |
|
0 commit comments