Skip to content

Commit 0c03735

Browse files
committed
raise AttributeError when method is not available and reorder interface
1 parent bdbd382 commit 0c03735

File tree

3 files changed

+148
-142
lines changed

3 files changed

+148
-142
lines changed

Lib/test/test_pyexpat.py

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,33 @@ def set_maximum_amplification(self, parser, max_factor):
867867
"""Set the maximum amplification factor for the tested protection."""
868868
raise NotImplementedError
869869

870+
def test_set_attack_protection_threshold_reached(self):
871+
raise NotImplementedError
872+
873+
def test_set_attack_protection_threshold_ignored(self):
874+
raise NotImplementedError
875+
876+
def test_set_attack_protection_threshold_arg_invalid_type(self):
877+
parser = expat.ParserCreate()
878+
setter = functools.partial(self.set_activation_threshold, parser)
879+
880+
self.assertRaises(TypeError, setter, 1.0)
881+
self.assertRaises(TypeError, setter, -1.5)
882+
self.assertRaises(ValueError, setter, -5)
883+
884+
def test_set_attack_protection_threshold_arg_invalid_range(self):
885+
_testcapi = import_helper.import_module("_testcapi")
886+
parser = expat.ParserCreate()
887+
setter = functools.partial(self.set_activation_threshold, parser)
888+
889+
self.assertRaises(OverflowError, setter, _testcapi.ULLONG_MAX + 1)
890+
891+
def test_set_attack_protection_threshold_fail_for_subparser(self):
892+
parser = expat.ParserCreate()
893+
subparser = parser.ExternalEntityParserCreate(None)
894+
setter = functools.partial(self.set_activation_threshold, subparser)
895+
self.assert_root_parser_failure(setter, 12345)
896+
870897
def test_set_maximum_amplification_reached(self):
871898
raise NotImplementedError
872899

@@ -899,33 +926,6 @@ def test_set_maximum_amplification_fail_for_subparser(self):
899926
setter = functools.partial(self.set_maximum_amplification, subparser)
900927
self.assert_root_parser_failure(setter, 123.45)
901928

902-
def test_set_attack_protection_threshold_reached(self):
903-
raise NotImplementedError
904-
905-
def test_set_attack_protection_threshold_ignored(self):
906-
raise NotImplementedError
907-
908-
def test_set_attack_protection_threshold_arg_invalid_type(self):
909-
parser = expat.ParserCreate()
910-
setter = functools.partial(self.set_activation_threshold, parser)
911-
912-
self.assertRaises(TypeError, setter, 1.0)
913-
self.assertRaises(TypeError, setter, -1.5)
914-
self.assertRaises(ValueError, setter, -5)
915-
916-
def test_set_attack_protection_threshold_arg_invalid_range(self):
917-
_testcapi = import_helper.import_module("_testcapi")
918-
parser = expat.ParserCreate()
919-
setter = functools.partial(self.set_activation_threshold, parser)
920-
921-
self.assertRaises(OverflowError, setter, _testcapi.ULLONG_MAX + 1)
922-
923-
def test_set_attack_protection_threshold_fail_for_subparser(self):
924-
parser = expat.ParserCreate()
925-
subparser = parser.ExternalEntityParserCreate(None)
926-
setter = functools.partial(self.set_activation_threshold, subparser)
927-
self.assert_root_parser_failure(setter, 12345)
928-
929929

930930
@unittest.skipIf(expat.version_info < (2, 7, 2), "requires Expat >= 2.7.2")
931931
class MemoryProtectionTest(AttackProtectionTestCases, unittest.TestCase):
@@ -940,31 +940,11 @@ def assert_active_protection(self, func, /, *args, **kwargs):
940940
msg = r"out of memory: line \d+, column \d+"
941941
self.assertRaisesRegex(expat.ExpatError, msg, func, *args, **kwargs)
942942

943-
def set_maximum_amplification(self, parser, max_factor):
944-
return parser.SetAllocTrackerMaximumAmplification(max_factor)
945-
946943
def set_activation_threshold(self, parser, threshold):
947944
return parser.SetAllocTrackerActivationThreshold(threshold)
948945

949-
def test_set_maximum_amplification_reached(self):
950-
parser = expat.ParserCreate()
951-
# Unconditionally enable maximum activation factor.
952-
self.set_activation_threshold(parser, 0)
953-
# Choose a max amplification factor expected to always be exceeded.
954-
self.assertIsNone(self.set_maximum_amplification(parser, 1.0))
955-
# Craft a payload for which the peak amplification factor is > 1.0.
956-
payload = self.exponential_expansion_payload(1, 2)
957-
self.assert_active_protection(parser.Parse, payload, True)
958-
959-
def test_set_maximum_amplification_ignored(self):
960-
parser = expat.ParserCreate()
961-
# Unconditionally enable maximum activation factor.
962-
self.set_activation_threshold(parser, 0)
963-
# Choose a max amplification factor expected to never be exceeded.
964-
self.assertIsNone(self.set_maximum_amplification(parser, 1e4))
965-
# Craft a payload for which the peak amplification factor is < 1e4.
966-
payload = self.exponential_expansion_payload(1, 2)
967-
self.assertIsNotNone(parser.Parse(payload, True))
946+
def set_maximum_amplification(self, parser, max_factor):
947+
return parser.SetAllocTrackerMaximumAmplification(max_factor)
968948

969949
def test_set_attack_protection_threshold_reached(self):
970950
parser = expat.ParserCreate()
@@ -986,6 +966,26 @@ def test_set_attack_protection_threshold_ignored(self):
986966
payload = self.exponential_expansion_payload(10, 4)
987967
self.assertIsNotNone(parser.Parse(payload, True))
988968

969+
def test_set_maximum_amplification_reached(self):
970+
parser = expat.ParserCreate()
971+
# Unconditionally enable maximum activation factor.
972+
self.set_activation_threshold(parser, 0)
973+
# Choose a max amplification factor expected to always be exceeded.
974+
self.assertIsNone(self.set_maximum_amplification(parser, 1.0))
975+
# Craft a payload for which the peak amplification factor is > 1.0.
976+
payload = self.exponential_expansion_payload(1, 2)
977+
self.assert_active_protection(parser.Parse, payload, True)
978+
979+
def test_set_maximum_amplification_ignored(self):
980+
parser = expat.ParserCreate()
981+
# Unconditionally enable maximum activation factor.
982+
self.set_activation_threshold(parser, 0)
983+
# Choose a max amplification factor expected to never be exceeded.
984+
self.assertIsNone(self.set_maximum_amplification(parser, 1e4))
985+
# Craft a payload for which the peak amplification factor is < 1e4.
986+
payload = self.exponential_expansion_payload(1, 2)
987+
self.assertIsNotNone(parser.Parse(payload, True))
988+
989989

990990
if __name__ == "__main__":
991991
unittest.main()

Modules/clinic/pyexpat.c.h

Lines changed: 64 additions & 48 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)