Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 37 additions & 23 deletions programs/zstdcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ static void errorOut(const char* msg)

/*! readU32FromCharChecked() :
* @return 0 if success, and store the result in *value.
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
* allows and interprets K, KB, KiB, M, MB, MiB, G, GB and GiB suffix.
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
* @return 1 if an overflow error occurs */
static int readU32FromCharChecked(const char** stringPtr, unsigned* value)
Expand All @@ -362,15 +362,22 @@ static int readU32FromCharChecked(const char** stringPtr, unsigned* value)
if (result < last) return 1; /* overflow error */
(*stringPtr)++ ;
}
if ((**stringPtr=='K') || (**stringPtr=='M')) {
unsigned const maxK = ((unsigned)(-1)) >> 10;
if (result > maxK) return 1; /* overflow error */
result <<= 10;
if (**stringPtr=='M') {
if (result > maxK) return 1; /* overflow error */
result <<= 10;
if ((**stringPtr=='K') || (**stringPtr=='M') || (**stringPtr=='G')) {
switch (**stringPtr) {
case 'K':
if (result > (((unsigned)-1) >> 10)) return 1; /* overflow error */
result <<= 10;
break;
case 'M':
if (result > (((unsigned)-1) >> 20)) return 1; /* overflow error */
result <<= 20;
break;
case 'G':
if (result > (((unsigned)-1) >> 30)) return 1; /* overflow error */
result <<= 30;
break;
}
(*stringPtr)++; /* skip `K` or `M` */
(*stringPtr)++; /* skip `K`, `M` or `G` */
if (**stringPtr=='i') (*stringPtr)++;
if (**stringPtr=='B') (*stringPtr)++;
}
Expand All @@ -380,7 +387,7 @@ static int readU32FromCharChecked(const char** stringPtr, unsigned* value)

/*! readU32FromChar() :
* @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, MiB, G, GB and GiB suffix.
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
* Note : function will exit() program if digit sequence overflows */
static unsigned readU32FromChar(const char** stringPtr) {
Expand All @@ -392,7 +399,7 @@ static unsigned readU32FromChar(const char** stringPtr) {

/*! readIntFromChar() :
* @return : signed 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, MiB, G, GB and GiB suffix.
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
* Note : function will exit() program if digit sequence overflows */
static int readIntFromChar(const char** stringPtr) {
Expand All @@ -409,7 +416,7 @@ static int readIntFromChar(const char** stringPtr) {

/*! readSizeTFromCharChecked() :
* @return 0 if success, and store the result in *value.
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
* allows and interprets K, KB, KiB, M, MB, MiB, G, GB and GiB suffix.
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
* @return 1 if an overflow error occurs */
static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)
Expand All @@ -424,15 +431,22 @@ static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)
if (result < last) return 1; /* overflow error */
(*stringPtr)++ ;
}
if ((**stringPtr=='K') || (**stringPtr=='M')) {
size_t const maxK = ((size_t)(-1)) >> 10;
if (result > maxK) return 1; /* overflow error */
result <<= 10;
if (**stringPtr=='M') {
if (result > maxK) return 1; /* overflow error */
result <<= 10;
if ((**stringPtr=='K') || (**stringPtr=='M') || (**stringPtr=='G')) {
switch (**stringPtr) {
case 'K':
if (result > (((size_t)-1) >> 10)) return 1; /* overflow error */
result <<= 10;
break;
case 'M':
if (result > (((size_t)-1) >> 20)) return 1; /* overflow error */
result <<= 20;
break;
case 'G':
if (result > (((size_t)-1) >> 30)) return 1; /* overflow error */
result <<= 30;
break;
}
(*stringPtr)++; /* skip `K` or `M` */
(*stringPtr)++; /* skip `K`, `M` or `G` */
if (**stringPtr=='i') (*stringPtr)++;
if (**stringPtr=='B') (*stringPtr)++;
}
Expand All @@ -442,7 +456,7 @@ static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)

/*! readSizeTFromChar() :
* @return : size_t 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, MiB, G, GB and GiB suffix.
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
* Note : function will exit() program if digit sequence overflows */
static size_t readSizeTFromChar(const char** stringPtr) {
Expand Down Expand Up @@ -830,7 +844,7 @@ static unsigned init_nbWorkers(unsigned defaultNbWorkers) {
NEXT_FIELD(__nb); \
_varu32 = readU32FromChar(&__nb); \
if(*__nb != 0) { \
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed"); \
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed"); \
} \
}

Expand All @@ -839,7 +853,7 @@ static unsigned init_nbWorkers(unsigned defaultNbWorkers) {
NEXT_FIELD(__nb); \
_varTsize = readSizeTFromChar(&__nb); \
if(*__nb != 0) { \
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed"); \
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed"); \
} \
}

Expand Down
24 changes: 24 additions & 0 deletions tests/cli-tests/basic/memlimit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,30 @@ rm file.zst
println "+ zstd --memory=1MiB file"
zstd -q --memory=1MiB file && die "Should allow numeric parameter with expected suffix"
rm file.zst
println "+ zstd --memory=1G file"
zstd -q --memory=1G file && die "Should allow numeric parameter with expected suffix"
rm file.zst
println "+ zstd --memory=1GB file"
zstd -q --memory=1GB file && die "Should allow numeric parameter with expected suffix"
rm file.zst
println "+ zstd --memory=1GiB file"
zstd -q --memory=1GiB file && die "Should allow numeric parameter with expected suffix"
rm file.zst
println "+ zstd --memory=3G file"
zstd -q --memory=3G file && die "Should allow numeric parameter with expected suffix"
rm file.zst
println "+ zstd --memory=3GB file"
zstd -q --memory=3GB file && die "Should allow numeric parameter with expected suffix"
rm file.zst
println "+ zstd --memory=3GiB file"
zstd -q --memory=3GiB file && die "Should allow numeric parameter with expected suffix"
rm file.zst
println "+ zstd --memory=4G file"
zstd --memory=4G file && die "Should not allow out-of-bound numeric parameter"
println "+ zstd --memory=4GB file"
zstd --memory=4GB file && die "Should not allow out-of-bound numeric parameter"
println "+ zstd --memory=4GiB file"
zstd --memory=4GiB file && die "Should not allow out-of-bound numeric parameter"

rm file
exit 0
21 changes: 15 additions & 6 deletions tests/cli-tests/basic/memlimit.sh.stderr.exact
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
Should allow numeric parameter without suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
Should allow numeric parameter with expected suffix
error: numeric value overflows 32-bit unsigned int
error: numeric value overflows 32-bit unsigned int
error: numeric value overflows 32-bit unsigned int
9 changes: 9 additions & 0 deletions tests/cli-tests/basic/memlimit.sh.stdout.exact
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,12 @@
+ zstd --memory=1M file
+ zstd --memory=1MB file
+ zstd --memory=1MiB file
+ zstd --memory=1G file
+ zstd --memory=1GB file
+ zstd --memory=1GiB file
+ zstd --memory=3G file
+ zstd --memory=3GB file
+ zstd --memory=3GiB file
+ zstd --memory=4G file
+ zstd --memory=4GB file
+ zstd --memory=4GiB file
10 changes: 9 additions & 1 deletion tests/playTests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1075,13 +1075,19 @@ cat tmp | zstd -14 -f --size-hint=11050 | zstd -t # slightly too high
cat tmp | zstd -14 -f --size-hint=10950 | zstd -t # slightly too low
cat tmp | zstd -14 -f --size-hint=22000 | zstd -t # considerably too high
cat tmp | zstd -14 -f --size-hint=5500 | zstd -t # considerably too low
println "test : allows and interprets K,KB,KiB,M,MB and MiB suffix"
println "test : allows and interprets K,KB,KiB,M,MB,MiB,G,GB and GiB suffix"
cat tmp | zstd -14 -f --size-hint=11K | zstd -t
cat tmp | zstd -14 -f --size-hint=11KB | zstd -t
cat tmp | zstd -14 -f --size-hint=11KiB | zstd -t
cat tmp | zstd -14 -f --size-hint=1M | zstd -t
cat tmp | zstd -14 -f --size-hint=1MB | zstd -t
cat tmp | zstd -14 -f --size-hint=1MiB | zstd -t
cat tmp | zstd -14 -f --size-hint=1G | zstd -t
cat tmp | zstd -14 -f --size-hint=1GB | zstd -t
cat tmp | zstd -14 -f --size-hint=1GiB | zstd -t
cat tmp | zstd -14 -f --size-hint=3G | zstd -t
cat tmp | zstd -14 -f --size-hint=3GB | zstd -t
cat tmp | zstd -14 -f --size-hint=3GiB | zstd -t


println "\n===> dictionary tests "
Expand Down Expand Up @@ -1684,6 +1690,8 @@ roundTripTest -g1M -P50 "1 --single-thread --long=29" " --memory=512MB"
roundTripTest -g1M -P50 "1 --single-thread --long=29 --zstd=wlog=28" " --memory=256MB"
roundTripTest -g1M -P50 "1 --single-thread --long=29" " --long=28 --memory=512MB"
roundTripTest -g1M -P50 "1 --single-thread --long=29" " --zstd=wlog=28 --memory=512MB"
roundTripTest -g1M -P50 "1 --single-thread --long=30" " --memory=1GB"
roundTripTest -g1M -P50 "1 --single-thread --long=30" " --zstd=wlog=29 --memory=1GB"


if [ "$ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP" -ne "1" ]; then
Expand Down