diff --git a/src/RpcMethodImpl.cc b/src/RpcMethodImpl.cc index f351f2a9..fd190773 100644 --- a/src/RpcMethodImpl.cc +++ b/src/RpcMethodImpl.cc @@ -1392,7 +1392,7 @@ SharedHandle ChangeUriRpcMethod::process (const RpcRequest& req, DownloadEngine* e) { const String* gidParam = checkRequiredParam(req, 0); - const Integer* indexParam = checkRequiredParam(req, 1); + const Integer* indexParam = checkRequiredInteger(req, 1, IntegerGE(1)); const List* delUrisParam = checkRequiredParam(req, 2); const List* addUrisParam = checkRequiredParam(req, 3); const Integer* posParam = checkParam(req, 4); diff --git a/src/RpcMethodImpl.h b/src/RpcMethodImpl.h index 1fe609af..56892047 100644 --- a/src/RpcMethodImpl.h +++ b/src/RpcMethodImpl.h @@ -76,6 +76,37 @@ const T* checkRequiredParam(const RpcRequest& req, size_t index) return checkParam(req, index, true); } +struct IntegerGE { + IntegerGE(int32_t min):min(min) {} + + bool operator()(const Integer* param, std::string* error) const + { + if(min <= param->i()) { + return true; + } else { + if(error) { + *error = fmt("the value must be greater than or equal to %d.", min); + } + return false; + } + } + + int32_t min; +}; + +template +const Integer* checkRequiredInteger(const RpcRequest& req, size_t index, + Validator validator) +{ + const Integer* param = checkRequiredParam(req, index); + std::string error; + if(!validator(param, &error)) { + throw DL_ABORT_EX(fmt("The integer parameter at %lu has invalid value: %s", + static_cast(index), error.c_str())); + } + return param; +} + template void toStringList(OutputIterator out, const List* src) { @@ -363,12 +394,9 @@ protected: (const RpcRequest& req, DownloadEngine* e) { const Integer* offsetParam = checkRequiredParam(req, 0); - const Integer* numParam = checkRequiredParam(req, 1); + const Integer* numParam = checkRequiredInteger(req, 1, IntegerGE(0)); const List* keysParam = checkParam(req, 2); - if(numParam->i() < 0) { - throw DL_ABORT_EX("The parameter num must be zero or positive integer."); - } int64_t offset = offsetParam->i(); int64_t num = numParam->i(); std::vector keys; diff --git a/test/RpcMethodTest.cc b/test/RpcMethodTest.cc index d28cc2fa..121357aa 100644 --- a/test/RpcMethodTest.cc +++ b/test/RpcMethodTest.cc @@ -999,6 +999,12 @@ void RpcMethodTest::testChangeUri_fail() RpcResponse res = m.execute(req, e_.get()); CPPUNIT_ASSERT_EQUAL(0, res.code); + req.params->set(1, Integer::g(0)); + res = m.execute(req, e_.get()); + // RPC request fails because 2nd argument is less than 1. + CPPUNIT_ASSERT_EQUAL(1, res.code); + + req.params->set(1, Integer::g(1)); req.params->set(0, String::g("2")); res = m.execute(req, e_.get()); // RPC request fails because GID#2 does not exist.