make IOBuf::gather() safe
authorAdam Simpkins <simpkins@fb.com>
Wed, 4 Dec 2013 02:38:07 +0000 (18:38 -0800)
committerJordan DeLong <jdelong@fb.com>
Fri, 20 Dec 2013 21:04:21 +0000 (13:04 -0800)
commitab4ee5fa6242d9686a93e2ef5e813c0fce65d2b2
treefdc64dd3d30faa0f67dfe28ac54aa5a6eeca75a2
parent29eecd37d773918cc0081938da7562852151c69f
make IOBuf::gather() safe

Summary:
Update IOBuf::gather() and RWCursor::gather() to check their arguments
more carefully, and throw std::overflow_errors if the caller attempts to
gather more data than is available.

The comments for IOBuf::gather() claimed that it ensured that maxLength
bytes would always be available when it returned.  However, if the total
chain length was less than maxLength, it would simply coalesce the full
chain and return successfully, even though fewer than maxLength bytes
were available.  This fixes the code to throw a std::overflow_error
rather than coalescing the chain.

Additional, this updates RWCursor::gather() to ensure that it does not
attempt to gather past the end of the IOBuf chain.  Previously it could
gather past the end of the chain, coalescing the head of the chain into
the tail.  This would free the IOBuf head, which was owned by an
external caller.

A new RWCursor::gatherAtMost() API is provided for callers that wish to
gather as much as requested if possible, but still succeed if less than
this is available.

Test Plan:
Updated the unit tests to test calling gather() with more bytes than
actually available.

Reviewed By: davejwatson@fb.com

FB internal diff: D1081995
folly/io/Cursor.h
folly/io/IOBuf.cpp
folly/io/IOBuf.h
folly/io/test/IOBufCursorTest.cpp
folly/io/test/IOBufTest.cpp