Repository: Geal/nom (rust)

Issue:
Panic in do_parse with take
Hi,

The following parser:
```rust
named!(parser02<&[u8],()>,
    do_parse!(
        hdr: take!(1) >>
        data: take!(18446744073709551615) >>
        ( () )
    )
);

#[test]
fn test02() {
    let data = b"0\x88\xff\xff\xff\xff\xff\xff\xff\xff00\x0f\x02\x000\x00\x00\x00\x00\x00\x0000\x0f\x00\xff\x0a\xbb\xff";
    let _ = parser02(data);
}
```

fails with an error:
```
thread 'test02' panicked at 'attempt to add with overflow', <do_parse macros>:33
```

The backtrace is not interesting, so not reported here.

The bug was originally discovered in https://github.com/rusticata/x509-parser/issues/1


Pull request description:
Check if requested length would overflow in do_parse, chain and tuple
This fixes #481 by using `overflowing_add`, in case the requested value would overflow when computing `Needed(consumed + needed)`.

Patch:
diff --git a/src/bytes.rs b/src/bytes.rs
index 7187eda..19343b0 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -725,7 +725,11 @@ macro_rules! length_bytes(
           let nb = nb as usize;
           if i1.input_len() < nb {
             use $crate::Offset;
-            $crate::IResult::Incomplete($crate::Needed::Size($i.offset(i1) + nb))
+            let (size,overflowed) = $i.offset(i1).overflowing_add(nb);
+            match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+            }
           } else {
             $crate::IResult::Done(i1.slice(nb..), i1.slice(..nb))
           }
diff --git a/src/multi.rs b/src/multi.rs
index a602d3c..0813719 100644
--- a/src/multi.rs
+++ b/src/multi.rs
@@ -165,8 +165,11 @@ macro_rules! many0(
             break;
           },
           $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
-            let size = i + ($i).input_len() - input.input_len();
-            ret = $crate::IResult::Incomplete($crate::Needed::Size(size));
+            let (size,overflowed) = i.overflowing_add(($i).input_len() - input.input_len());
+            ret = match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+            };
             break;
           },
           $crate::IResult::Done(i, o)                          => {
@@ -245,8 +248,12 @@ macro_rules! many1(
                   break;
                 },
                 $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+                  let (size,overflowed) = i.overflowing_add(($i).input_len() - input.input_len());
                   incomplete = ::std::option::Option::Some(
-                    $crate::Needed::Size(i + ($i).input_len() - input.input_len())
+                    match overflowed {
+                        true  => $crate::Needed::Unknown,
+                        false => $crate::Needed::Size(size),
+                    }
                   );
                   break;
                 },
@@ -327,8 +334,11 @@ macro_rules! many_till(
                 break;
               },
               $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
-                let size = i + ($i).input_len() - input.input_len();
-                ret = $crate::IResult::Incomplete($crate::Needed::Size(size));
+                let (size,overflowed) = i.overflowing_add(($i).input_len() - input.input_len());
+                ret = match overflowed {
+                    true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                    false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+                };
                 break;
               },
               $crate::IResult::Done(i, o)                          => {
@@ -411,8 +421,12 @@ macro_rules! many_m_n(
             break;
           },
           $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            let (size,overflowed) = i.overflowing_add(($i).input_len() - input.input_len());
             incomplete = ::std::option::Option::Some(
-              $crate::Needed::Size(i + ($i).input_len() - input.input_len())
+              match overflowed {
+                  true  => $crate::Needed::Unknown,
+                  false => $crate::Needed::Size(size),
+              }
             );
             break;
           },
@@ -495,9 +509,13 @@ macro_rules! count(
             break;
           }
           $crate::IResult::Incomplete($crate::Needed::Size(sz)) => {
-            ret = $crate::IResult::Incomplete($crate::Needed::Size(
-              sz + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input)
-            ));
+            let (size,overflowed) = sz.overflowing_add(
+              $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input)
+            );
+            ret = match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+            };
             break;
           }
         }
@@ -565,9 +583,13 @@ macro_rules! count_fixed (
             break;
           }
           $crate::IResult::Incomplete($crate::Needed::Size(sz)) => {
-            ret = $crate::IResult::Incomplete($crate::Needed::Size(
-              sz + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input)
-            ));
+            let (size,overflowed) = sz.overflowing_add(
+              $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&input)
+            );
+            ret = match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+            };
             break;
           }
         }
@@ -595,9 +617,13 @@ macro_rules! length_count(
             $crate::IResult::Error(e)                            => $crate::IResult::Error(e),
             $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
             $crate::IResult::Incomplete($crate::Needed::Size(n)) => {
-              $crate::IResult::Incomplete($crate::Needed::Size(
-                n + $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
-              ))
+              let (size,overflowed) = n.overflowing_add(
+                $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
+              );
+              match overflowed {
+                  true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                  false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+              }
             },
             $crate::IResult::Done(i2, o2)  =>  $crate::IResult::Done(i2, o2)
           }
@@ -634,9 +660,13 @@ macro_rules! length_data(
           $crate::IResult::Error(e)                            => $crate::IResult::Error(e),
           $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
           $crate::IResult::Incomplete($crate::Needed::Size(n)) => {
-            $crate::IResult::Incomplete($crate::Needed::Size(
-              n +$crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
-            ))
+            let (size,overflowed) = n.overflowing_add(
+              $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
+            );
+            match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+            }
           },
           $crate::IResult::Done(i2, o2)  =>  $crate::IResult::Done(i2, o2)
         }
@@ -665,9 +695,13 @@ macro_rules! length_value(
             $crate::IResult::Error(e)                            => $crate::IResult::Error(e),
             $crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
             $crate::IResult::Incomplete($crate::Needed::Size(n)) => {
-              $crate::IResult::Incomplete($crate::Needed::Size(
-                n +$crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
-              ))
+              let (size,overflowed) = n.overflowing_add(
+                $crate::InputLength::input_len(&($i)) - $crate::InputLength::input_len(&i)
+              );
+              match overflowed {
+                  true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                  false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+              }
             },
             $crate::IResult::Done(i2, o2)  => {
               match complete!(o2, $submac2!($($args2)*)) {
@@ -745,8 +779,11 @@ macro_rules! fold_many0(
             break;
           },
           $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
-            let size = i + ($i).input_len() - input.input_len();
-            ret = $crate::IResult::Incomplete($crate::Needed::Size(size));
+            let (size,overflowed) = i.overflowing_add( ($i).input_len() - input.input_len() );
+            ret = match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false => $crate::IResult::Incomplete($crate::Needed::Size(size)),
+            };
             break;
           },
           $crate::IResult::Done(i, o)                          => {
@@ -832,8 +869,12 @@ macro_rules! fold_many1(
                   break;
                 },
                 $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+                  let (size,overflowed) = i.overflowing_add( ($i).input_len() - input.input_len() );
                   incomplete = ::std::option::Option::Some(
-                    $crate::Needed::Size(i + ($i).input_len() - input.input_len())
+                      match overflowed {
+                          true  => $crate::Needed::Unknown,
+                          false => $crate::Needed::Size(size),
+                      }
                   );
                   break;
                 },
@@ -922,8 +963,12 @@ macro_rules! fold_many_m_n(
             break;
           },
           $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+            let (size,overflowed) = i.overflowing_add( ($i).input_len() - input.input_len() );
             incomplete = ::std::option::Option::Some(
-              $crate::Needed::Size(i + ($i).input_len() - input.input_len())
+              match overflowed {
+                  true  => $crate::Needed::Unknown,
+                  false => $crate::Needed::Size(size),
+              }
             );
             break;
           },
diff --git a/src/sequence.rs b/src/sequence.rs
index ae188ad..6bb804a 100644
--- a/src/sequence.rs
+++ b/src/sequence.rs
@@ -85,8 +85,13 @@ macro_rules! chaining_parser (
         $crate::IResult::Error(e)      => $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,_)     => {
           chaining_parser!(i,
             $consumed + ($crate::InputLength::input_len(&($i)) -
@@ -107,8 +112,13 @@ macro_rules! chaining_parser (
         match inc {
           $crate::Needed::Unknown =>
             $crate::IResult::Incomplete($crate::Needed::Unknown),
-          $crate::Needed::Size(i) =>
-            $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+          $crate::Needed::Size(i) => {
+            let (needed,overflowed) = $consumed.overflowing_add(i);
+            match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+            }
+          },
         }
       } else {
         let input = if let $crate::IResult::Done(i,_) = res {
@@ -133,8 +143,13 @@ macro_rules! chaining_parser (
         $crate::IResult::Error(e)      => $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,o)     => {
           let $field = o;
           chaining_parser!(i,
@@ -155,8 +170,13 @@ macro_rules! chaining_parser (
         $crate::IResult::Error(e)      => $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,o)     => {
           let mut $field = o;
           chaining_parser!(i,
@@ -178,8 +198,13 @@ macro_rules! chaining_parser (
         match inc {
           $crate::Needed::Unknown =>
             $crate::IResult::Incomplete($crate::Needed::Unknown),
-          $crate::Needed::Size(i) =>
-            $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+          $crate::Needed::Size(i) => {
+            let (needed,overflowed) = $consumed.overflowing_add(i);
+            match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+            }
+          },
         }
       } else {
         let ($field,input) = if let $crate::IResult::Done(i,o) = res {
@@ -205,8 +230,13 @@ macro_rules! chaining_parser (
         match inc {
           $crate::Needed::Unknown =>
             $crate::IResult::Incomplete($crate::Needed::Unknown),
-          $crate::Needed::Size(i) =>
-            $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+          $crate::Needed::Size(i) => {
+            let (needed,overflowed) = $consumed.overflowing_add(i);
+            match overflowed {
+                true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+                false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+            }
+          },
         }
       } else {
         let (mut $field,input) = if let $crate::IResult::Done(i,o) = res {
@@ -231,8 +261,13 @@ macro_rules! chaining_parser (
       $crate::IResult::Error(e)      => $crate::IResult::Error(e),
       $crate::IResult::Incomplete($crate::Needed::Unknown) =>
         $crate::IResult::Incomplete($crate::Needed::Unknown),
-      $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-        $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+        let (needed,overflowed) = $consumed.overflowing_add(i);
+        match overflowed {
+            true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+            false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+        }
+      },
       $crate::IResult::Done(i,_)     => {
         $crate::IResult::Done(i, $assemble())
       }
@@ -249,8 +284,13 @@ macro_rules! chaining_parser (
       match inc {
         $crate::Needed::Unknown =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::Needed::Size(i) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::Needed::Size(i) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
       }
     } else {
       let input = if let $crate::IResult::Done(i,_) = res {
@@ -271,8 +311,13 @@ macro_rules! chaining_parser (
       $crate::IResult::Error(e)      => $crate::IResult::Error(e),
       $crate::IResult::Incomplete($crate::Needed::Unknown) =>
         $crate::IResult::Incomplete($crate::Needed::Unknown),
-      $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-        $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+        let (needed,overflowed) = $consumed.overflowing_add(i);
+        match overflowed {
+            true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+            false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+        }
+      },
       $crate::IResult::Done(i,o)     => {
         let $field = o;
         $crate::IResult::Done(i, $assemble())
@@ -289,8 +334,13 @@ macro_rules! chaining_parser (
       $crate::IResult::Error(e)      => $crate::IResult::Error(e),
       $crate::IResult::Incomplete($crate::Needed::Unknown) =>
         $crate::IResult::Incomplete($crate::Needed::Unknown),
-      $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-        $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+        let (needed,overflowed) = $consumed.overflowing_add(i);
+        match overflowed {
+            true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+            false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+        }
+      },
       $crate::IResult::Done(i,o)     => {
         let mut $field = o;
         $crate::IResult::Done(i, $assemble())
@@ -308,8 +358,13 @@ macro_rules! chaining_parser (
       match inc {
         $crate::Needed::Unknown =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::Needed::Size(i) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::Needed::Size(i) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
       }
     } else {
       let ($field,input) = if let $crate::IResult::Done(i,o) = res {
@@ -331,8 +386,13 @@ macro_rules! chaining_parser (
       match inc {
         $crate::Needed::Unknown =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::Needed::Size(i) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::Needed::Size(i) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
       }
     } else {
       let (mut $field,input) = if let $crate::IResult::Done(i,o) = res {
@@ -407,8 +467,13 @@ macro_rules! tuple_parser (
           $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,o)     => {
           tuple_parser!(i,
             $consumed + ($crate::InputLength::input_len(&($i)) -
@@ -424,8 +489,13 @@ macro_rules! tuple_parser (
           $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,o)     => {
           tuple_parser!(i,
             $consumed + ($crate::InputLength::input_len(&($i)) -
@@ -444,8 +514,13 @@ macro_rules! tuple_parser (
           $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,o)     => {
           $crate::IResult::Done(i, (o))
         }
@@ -459,8 +534,13 @@ macro_rules! tuple_parser (
           $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,o)     => {
           $crate::IResult::Done(i, ($($parsed),* , o))
         }
@@ -700,8 +780,13 @@ macro_rules! do_parse (
         $crate::IResult::Error(e)      => $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,_)     => {
           do_parse!(__impl i,
             $consumed + ($crate::InputLength::input_len(&($i)) -
@@ -721,8 +806,13 @@ macro_rules! do_parse (
         $crate::IResult::Error(e)      => $crate::IResult::Error(e),
         $crate::IResult::Incomplete($crate::Needed::Unknown) =>
           $crate::IResult::Incomplete($crate::Needed::Unknown),
-        $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-          $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+        $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+          let (needed,overflowed) = $consumed.overflowing_add(i);
+          match overflowed {
+              true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+              false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+          }
+        },
         $crate::IResult::Done(i,o)     => {
           let $field = o;
           do_parse!(__impl i,
@@ -743,8 +833,13 @@ macro_rules! do_parse (
       $crate::IResult::Error(e)      => $crate::IResult::Error(e),
       $crate::IResult::Incomplete($crate::Needed::Unknown) =>
         $crate::IResult::Incomplete($crate::Needed::Unknown),
-      $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-        $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+        let (needed,overflowed) = $consumed.overflowing_add(i);
+        match overflowed {
+            true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+            false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+        }
+      },
       $crate::IResult::Done(i,_)     => {
         $crate::IResult::Done(i, ( $($rest)* ))
       },
@@ -760,8 +855,13 @@ macro_rules! do_parse (
       $crate::IResult::Error(e)      => $crate::IResult::Error(e),
       $crate::IResult::Incomplete($crate::Needed::Unknown) =>
         $crate::IResult::Incomplete($crate::Needed::Unknown),
-      $crate::IResult::Incomplete($crate::Needed::Size(i)) =>
-        $crate::IResult::Incomplete($crate::Needed::Size($consumed + i)),
+      $crate::IResult::Incomplete($crate::Needed::Size(i)) => {
+        let (needed,overflowed) = $consumed.overflowing_add(i);
+        match overflowed {
+            true  => $crate::IResult::Incomplete($crate::Needed::Unknown),
+            false =>  $crate::IResult::Incomplete($crate::Needed::Size(needed)),
+        }
+      },
       $crate::IResult::Done(i,o)     => {
         let $field = o;
         $crate::IResult::Done(i, ( $($rest)* ))


Test patch:
diff --git a/tests/overflow.rs b/tests/overflow.rs
new file mode 100644
index 0000000..1423931
--- /dev/null
+++ b/tests/overflow.rs
@@ -0,0 +1,112 @@
+#[macro_use]
+extern crate nom;
+
+use nom::{IResult,Needed,be_u8,be_u64};
+
+// Parser definition
+
+// We request a length that would trigger an overflow if computing consumed + requested
+named!(parser01<&[u8],()>,
+    do_parse!(
+        hdr: take!(1) >>
+        data: take!(18446744073709551615) >>
+        ( () )
+    )
+);
+
+// We request a length that would trigger an overflow if computing consumed + requested
+named!(parser02<&[u8],()>,
+    chain!(
+        hdr: take!(1) ~
+        data: take!(18446744073709551615),
+        || ()
+    )
+);
+
+// We request a length that would trigger an overflow if computing consumed + requested
+named!(parser03<&[u8],(&[u8],&[u8])>,
+    tuple!(take!(1),take!(18446744073709551615))
+);
+
+#[test]
+fn overflow_incomplete_do_parse() {
+  assert_eq!(parser01(&b"3"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_chain() {
+  assert_eq!(parser02(&b"3"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_tuple() {
+  assert_eq!(parser03(&b"3"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_length_bytes() {
+ named!(multi<&[u8], Vec<&[u8]> >, many0!( length_bytes!(be_u64) ) );
+
+ // Trigger an overflow in length_bytes
+ assert_eq!(multi(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xff\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_many0() {
+ named!(multi<&[u8], Vec<&[u8]> >, many0!( length_bytes!(be_u64) ) );
+
+ // Trigger an overflow in many0
+ assert_eq!(multi(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xef\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_many1() {
+ named!(multi<&[u8], Vec<&[u8]> >, many1!( length_bytes!(be_u64) ) );
+
+ // Trigger an overflow in many1
+ assert_eq!(multi(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xef\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_many_till() {
+ named!(multi<&[u8], (Vec<&[u8]>, &[u8]) >, many_till!( length_bytes!(be_u64), tag!("abc") ) );
+
+ // Trigger an overflow in many_till
+ assert_eq!(multi(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xef\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_many_m_n() {
+ named!(multi<&[u8], Vec<&[u8]> >, many_m_n!(2, 4, length_bytes!(be_u64) ) );
+
+ // Trigger an overflow in many_m_n
+ assert_eq!(multi(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xef\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_count() {
+ named!(counter<&[u8], Vec<&[u8]> >, count!( length_bytes!(be_u64), 2 ) );
+
+ assert_eq!(counter(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xef\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_count_fixed() {
+ named!(counter< [&[u8]; 2] >, count_fixed!( &[u8], length_bytes!(be_u64), 2 ) );
+
+ assert_eq!(counter(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xef\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_length_count() {
+ named!(multi<&[u8], Vec<&[u8]> >, length_count!( be_u8, length_bytes!(be_u64) ) );
+
+ assert_eq!(multi(&b"\x04\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xee\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}
+
+#[test]
+fn overflow_incomplete_length_data() {
+ named!(multi<&[u8], Vec<&[u8]> >, many0!( length_data!(be_u64) ) );
+
+ assert_eq!(multi(&b"\x00\x00\x00\x00\x00\x00\x00\x01\xaa\xff\xff\xff\xff\xff\xff\xff\xff\xaa"[..]), IResult::Incomplete(Needed::Unknown));
+}