Merge pull request #1131 from facebook/zstdcli

minor: control numeric argument overflow
This commit is contained in:
Yann Collet 2018-05-14 11:53:58 -07:00 committed by GitHub
commit 174bd3d4a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 4 deletions

View File

@ -219,20 +219,34 @@ static int exeNameMatch(const char* exeName, const char* test)
(exeName[strlen(test)] == '\0' || exeName[strlen(test)] == '.'); (exeName[strlen(test)] == '\0' || exeName[strlen(test)] == '.');
} }
static void errorOut(const char* msg)
{
DISPLAY("%s \n", msg); exit(1);
}
/*! readU32FromChar() : /*! readU32FromChar() :
* @return : unsigned integer value read from input in `char` format. * @return : unsigned integer value read from input in `char` format.
* allows and interprets K, KB, KiB, M, MB and MiB suffix. * allows and interprets K, KB, KiB, M, MB and MiB suffix.
* Will also modify `*stringPtr`, advancing it to position where it stopped reading. * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
* Note : function result can overflow if digit string > MAX_UINT */ * Note : function will exit() program if digit sequence overflows */
static unsigned readU32FromChar(const char** stringPtr) static unsigned readU32FromChar(const char** stringPtr)
{ {
const char errorMsg[] = "error: numeric value too large";
unsigned result = 0; unsigned result = 0;
while ((**stringPtr >='0') && (**stringPtr <='9')) while ((**stringPtr >='0') && (**stringPtr <='9')) {
unsigned const max = (((unsigned)(-1)) / 10) - 1;
if (result > max) errorOut(errorMsg);
result *= 10, result += **stringPtr - '0', (*stringPtr)++ ; result *= 10, result += **stringPtr - '0', (*stringPtr)++ ;
}
if ((**stringPtr=='K') || (**stringPtr=='M')) { if ((**stringPtr=='K') || (**stringPtr=='M')) {
unsigned const maxK = ((unsigned)(-1)) >> 10;
if (result > maxK) errorOut(errorMsg);
result <<= 10; result <<= 10;
if (**stringPtr=='M') result <<= 10; if (**stringPtr=='M') {
(*stringPtr)++ ; if (result > maxK) errorOut(errorMsg);
result <<= 10;
}
(*stringPtr)++; /* skip `K` or `M` */
if (**stringPtr=='i') (*stringPtr)++; if (**stringPtr=='i') (*stringPtr)++;
if (**stringPtr=='B') (*stringPtr)++; if (**stringPtr=='B') (*stringPtr)++;
} }

View File

@ -108,6 +108,8 @@ $ECHO "test : --fast aka negative compression levels"
$ZSTD --fast -f tmp # == -1 $ZSTD --fast -f tmp # == -1
$ZSTD --fast=3 -f tmp # == -3 $ZSTD --fast=3 -f tmp # == -3
$ZSTD --fast=200000 -f tmp # == no compression $ZSTD --fast=200000 -f tmp # == no compression
$ECHO "test : too large numeric argument"
$ZSTD --fast=9999999999 -f tmp && die "should have refused numeric value"
$ECHO "test : compress to stdout" $ECHO "test : compress to stdout"
$ZSTD tmp -c > tmpCompressed $ZSTD tmp -c > tmpCompressed
$ZSTD tmp --stdout > tmpCompressed # long command format $ZSTD tmp --stdout > tmpCompressed # long command format