Jelajahi Sumber

Only accepts 32 bit integer values from int and i4 elements in XML-RPC.

Fixed overflow in AbstractPaginationRpcMethod::getPaginationRange().
Fixes bug#3494165
Tatsuhiro Tsujikawa 13 tahun lalu
induk
melakukan
ad11d746f0
3 mengubah file dengan 38 tambahan dan 8 penghapusan
  1. 6 6
      src/RpcMethodImpl.h
  2. 2 2
      src/XmlRpcRequestParserStateImpl.cc
  3. 30 0
      test/RpcMethodTest.cc

+ 6 - 6
src/RpcMethodImpl.h

@@ -331,11 +331,11 @@ private:
   template<typename InputIterator>
   std::pair<InputIterator, InputIterator>
   getPaginationRange
-  (int offset, int num, InputIterator first, InputIterator last)
+  (int64_t offset, int64_t num, InputIterator first, InputIterator last)
   {
-    int size = std::distance(first, last);
+    int64_t size = std::distance(first, last);
     if(offset < 0) {
-      int tempoffset = offset+size;
+      int64_t tempoffset = offset+size;
       if(tempoffset < 0) {
         return std::make_pair(last, last);
       }
@@ -347,7 +347,7 @@ private:
     } else if(size <= offset) {
       return std::make_pair(last, last);
     }
-    int lastDistance;
+    int64_t lastDistance;
     if(size < offset+num) {
       lastDistance = size;
     } else {
@@ -369,8 +369,8 @@ protected:
     if(numParam->i() < 0) {
       throw DL_ABORT_EX("The parameter num must be zero or positive integer.");
     }
-    int offset = offsetParam->i();
-    int num = numParam->i();
+    int64_t offset = offsetParam->i();
+    int64_t num = numParam->i();
     std::vector<std::string> keys;
     toStringList(std::back_inserter(keys), keysParam);
     const std::deque<SharedHandle<T> >& items = getItems(e);

+ 2 - 2
src/XmlRpcRequestParserStateImpl.cc

@@ -200,8 +200,8 @@ void IntXmlRpcRequestParserState::endElement
  const char* name,
  const std::string& characters)
 {
-  int64_t value;
-  if(util::parseLLIntNoThrow(value, characters)) {
+  int32_t value;
+  if(util::parseIntNoThrow(value, characters)) {
     psm->setCurrentFrameValue(Integer::g(value));
   } else {
     // nothing to do here: We just leave current frame value to null.

+ 30 - 0
test/RpcMethodTest.cc

@@ -652,6 +652,36 @@ void RpcMethodTest::testTellWaiting()
   CPPUNIT_ASSERT_EQUAL(0, res.code);
   resParams = downcast<List>(res.param);
   CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
+
+  // offset = INT32_MAX
+  req.params->set(0, Integer::g(INT32_MAX));
+  req.params->set(1, Integer::g(1));
+  res = m.execute(req, e_.get());
+  CPPUNIT_ASSERT_EQUAL(0, res.code);
+  resParams = downcast<List>(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
+  // num = INT32_MAX
+  req.params->set(0, Integer::g(1));
+  req.params->set(1, Integer::g(INT32_MAX));
+  res = m.execute(req, e_.get());
+  CPPUNIT_ASSERT_EQUAL(0, res.code);
+  resParams = downcast<List>(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
+  // offset=INT32_MAX and num = INT32_MAX
+  req.params->set(0, Integer::g(INT32_MAX));
+  req.params->set(1, Integer::g(INT32_MAX));
+  res = m.execute(req, e_.get());
+  CPPUNIT_ASSERT_EQUAL(0, res.code);
+  resParams = downcast<List>(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
+  // offset=INT32_MIN and num = INT32_MAX
+  req.params->set(0, Integer::g(INT32_MIN));
+  req.params->set(1, Integer::g(INT32_MAX));
+  res = m.execute(req, e_.get());
+  CPPUNIT_ASSERT_EQUAL(0, res.code);
+  resParams = downcast<List>(res.param);
+  CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
+
   // negative offset
   req = RpcRequest(TellWaitingRpcMethod::getMethodName(), List::g());
   req.params->append(Integer::g(-1));