Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions Lib/test/test_xmlrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import contextlib
from test import support
from test.support import os_helper
from test.support import script_helper
from test.support import socket_helper
from test.support import threading_helper
from test.support import ALWAYS_EQ, LARGEST, SMALLEST
Expand Down Expand Up @@ -129,6 +130,56 @@ def test_dump_big_long(self):
def test_dump_bad_dict(self):
self.assertRaises(TypeError, xmlrpclib.dumps, ({(1,2,3): 1},))

def test_dump_invalid_params(self):
for params in ([], ["x"], {"x": 1}, "abc", 1):
with self.subTest(params=params):
with self.assertRaisesRegex(
TypeError,
"^argument must be tuple or Fault instance$",
):
xmlrpclib.dumps(params)

def test_dump_invalid_methodresponse(self):
for params in ((), (1, 2)):
with self.subTest(params=params):
with self.assertRaisesRegex(
ValueError,
"^response tuple must be a singleton$",
):
xmlrpclib.dumps(params, methodresponse=True)

def test_dump_invalid_params_optimized(self):
code = r"""
import xmlrpc.client as xmlrpclib

if __debug__:
raise AssertionError("expected optimized mode")

def check(exc_type, message, func):
try:
func()
except exc_type as exc:
if str(exc) != message:
raise AssertionError(str(exc))
else:
raise AssertionError(f"{exc_type.__name__} not raised")

for params in [], ["x"], {"x": 1}, "abc", 1:
check(
TypeError,
"argument must be tuple or Fault instance",
lambda params=params: xmlrpclib.dumps(params),
)

for params in (), (1, 2):
check(
ValueError,
"response tuple must be a singleton",
lambda params=params: xmlrpclib.dumps(params, methodresponse=True),
)
"""
script_helper.assert_python_ok("-O", "-c", code)

def test_dump_recursive_seq(self):
l = [1,2,3]
t = [3,4,5,l]
Expand Down
7 changes: 4 additions & 3 deletions Lib/xmlrpc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,11 +938,12 @@ def dumps(params, methodname=None, methodresponse=None, encoding=None,
where necessary.
"""

assert isinstance(params, (tuple, Fault)), "argument must be tuple or Fault instance"
if not isinstance(params, (tuple, Fault)):
raise TypeError("argument must be tuple or Fault instance")
if isinstance(params, Fault):
methodresponse = 1
elif methodresponse and isinstance(params, tuple):
assert len(params) == 1, "response tuple must be a singleton"
elif methodresponse and len(params) != 1:
raise ValueError("response tuple must be a singleton")

if not encoding:
encoding = "utf-8"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Validate :func:`xmlrpc.client.dumps` arguments with explicit runtime checks
so invalid arguments are rejected consistently when Python runs with
optimization enabled.
Loading