diff --git a/tests/unit/legacy/api/xmlrpc/test_xmlrpc.py b/tests/unit/legacy/api/xmlrpc/test_xmlrpc.py index c89f82fc7dfa..5b5cfb13ccb2 100644 --- a/tests/unit/legacy/api/xmlrpc/test_xmlrpc.py +++ b/tests/unit/legacy/api/xmlrpc/test_xmlrpc.py @@ -858,3 +858,14 @@ def test_missing_multicall_method(self): assert exc.value.faultString == ( 'ValueError: Method name not provided' ) + + def test_too_many_multicalls_method(self): + request = pretend.stub() + args = [{'methodName': 'nah'}] * 21 + + with pytest.raises(xmlrpc.XMLRPCWrappedError) as exc: + xmlrpc.multicall(request, args) + + assert exc.value.faultString == ( + 'ValueError: Multicall limit is 20 calls' + ) diff --git a/warehouse/legacy/api/xmlrpc/views.py b/warehouse/legacy/api/xmlrpc/views.py index 7c904fbdbc54..0650b8a663cf 100644 --- a/warehouse/legacy/api/xmlrpc/views.py +++ b/warehouse/legacy/api/xmlrpc/views.py @@ -33,6 +33,9 @@ ) +_MAX_MULTICALLS = 20 + + def xmlrpc_method(**kwargs): """ Support multiple endpoints serving the same views by chaining calls to @@ -453,8 +456,11 @@ def multicall(request, args): ) if not all(arg.get('methodName') for arg in args): + raise XMLRPCWrappedError(ValueError('Method name not provided')) + + if len(args) > _MAX_MULTICALLS: raise XMLRPCWrappedError( - ValueError('Method name not provided') + ValueError(f'Multicall limit is {_MAX_MULTICALLS} calls') ) responses = []