Explorar o código

Added checkRequiredInteger() to check integer param is in valid range.

Ensure that fileIndex in aria2.changeUri RPC method is greater than or
equal to 1.
Tatsuhiro Tsujikawa %!s(int64=13) %!d(string=hai) anos
pai
achega
f4e0eae904
Modificáronse 3 ficheiros con 39 adicións e 5 borrados
  1. 1 1
      src/RpcMethodImpl.cc
  2. 32 4
      src/RpcMethodImpl.h
  3. 6 0
      test/RpcMethodTest.cc

+ 1 - 1
src/RpcMethodImpl.cc

@@ -1392,7 +1392,7 @@ SharedHandle<ValueBase> ChangeUriRpcMethod::process
 (const RpcRequest& req, DownloadEngine* e)
 {
   const String* gidParam = checkRequiredParam<String>(req, 0);
-  const Integer* indexParam = checkRequiredParam<Integer>(req, 1);
+  const Integer* indexParam = checkRequiredInteger(req, 1, IntegerGE(1));
   const List* delUrisParam = checkRequiredParam<List>(req, 2);
   const List* addUrisParam = checkRequiredParam<List>(req, 3);
   const Integer* posParam = checkParam<Integer>(req, 4);

+ 32 - 4
src/RpcMethodImpl.h

@@ -76,6 +76,37 @@ const T* checkRequiredParam(const RpcRequest& req, size_t index)
   return checkParam<T>(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<typename Validator>
+const Integer* checkRequiredInteger(const RpcRequest& req, size_t index,
+                                    Validator validator)
+{
+  const Integer* param = checkRequiredParam<Integer>(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<unsigned long>(index), error.c_str()));
+  }
+  return param;
+}
+
 template<typename OutputIterator>
 void toStringList(OutputIterator out, const List* src)
 {
@@ -363,12 +394,9 @@ protected:
   (const RpcRequest& req, DownloadEngine* e)
   {
     const Integer* offsetParam = checkRequiredParam<Integer>(req, 0);
-    const Integer* numParam = checkRequiredParam<Integer>(req, 1);
+    const Integer* numParam = checkRequiredInteger(req, 1, IntegerGE(0));
     const List* keysParam = checkParam<List>(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<std::string> keys;

+ 6 - 0
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.