mirror of
https://github.com/facebook/zstd.git
synced 2025-03-07 09:26:03 +02:00
Merge pull request #4113 from facebook/fix4110
formatString_u() can display numbers > 100
This commit is contained in:
commit
10e2a8042c
@ -139,52 +139,61 @@ static const size_t maxMemory = (sizeof(size_t) == 4)
|
||||
return r; \
|
||||
}
|
||||
|
||||
/* replacement for snprintf(), which is not supported by C89
|
||||
* sprintf() would be the supported one, but it's labelled unsafe,
|
||||
* so some modern static analyzer will flag it as such, making it unusable.
|
||||
* formatString_u() replaces snprintf() for the specific case where there are only %u arguments */
|
||||
static size_t uintSize(unsigned value)
|
||||
{
|
||||
size_t size = 1;
|
||||
while (value >= 10) {
|
||||
size++;
|
||||
value /= 10;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Note: presume @buffer is large enough */
|
||||
static void writeUint_varLen(char* buffer, size_t capacity, unsigned value)
|
||||
{
|
||||
int endPos = (int)uintSize(value) - 1;
|
||||
assert(uintSize(value) >= 1);
|
||||
assert(uintSize(value) < capacity); (void)capacity;
|
||||
while (endPos >= 0) {
|
||||
char c = '0' + (char)(value % 10);
|
||||
buffer[endPos--] = c;
|
||||
value /= 10;
|
||||
}
|
||||
}
|
||||
|
||||
/* replacement for snprintf(), which is not supported by C89.
|
||||
* sprintf() would be the supported one, but it's labelled unsafe:
|
||||
* modern static analyzer will flag sprintf() as dangerous, making it unusable.
|
||||
* formatString_u() replaces snprintf() for the specific case where there is only one %u argument */
|
||||
static int formatString_u(char* buffer, size_t buffer_size, const char* formatString, unsigned int value)
|
||||
{
|
||||
size_t const valueSize = uintSize(value);
|
||||
size_t written = 0;
|
||||
int i;
|
||||
assert(value <= 100);
|
||||
|
||||
for (i = 0; formatString[i] != '\0' && written < buffer_size - 1; ++i) {
|
||||
for (i = 0; formatString[i] != '\0' && written < buffer_size - 1; i++) {
|
||||
if (formatString[i] != '%') {
|
||||
buffer[written++] = formatString[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (formatString[++i] == 'u') {
|
||||
/* Handle single digit */
|
||||
if (value < 10) {
|
||||
buffer[written++] = '0' + (char)value;
|
||||
} else if (value < 100) {
|
||||
/* Handle two digits */
|
||||
if (written >= buffer_size - 2) {
|
||||
return -1; /* buffer overflow */
|
||||
}
|
||||
buffer[written++] = '0' + (char)(value / 10);
|
||||
buffer[written++] = '0' + (char)(value % 10);
|
||||
} else { /* 100 */
|
||||
if (written >= buffer_size - 3) {
|
||||
return -1; /* buffer overflow */
|
||||
}
|
||||
buffer[written++] = '1';
|
||||
buffer[written++] = '0';
|
||||
buffer[written++] = '0';
|
||||
}
|
||||
i++;
|
||||
if (formatString[i] == 'u') {
|
||||
if (written + valueSize >= buffer_size) abort(); /* buffer not large enough */
|
||||
writeUint_varLen(buffer + written, buffer_size - written, value);
|
||||
written += valueSize;
|
||||
} else if (formatString[i] == '%') { /* Check for escaped percent sign */
|
||||
buffer[written++] = '%';
|
||||
} else {
|
||||
return -1; /* unsupported format */
|
||||
abort(); /* unsupported format */
|
||||
}
|
||||
}
|
||||
|
||||
if (written < buffer_size) {
|
||||
buffer[written] = '\0';
|
||||
} else {
|
||||
buffer[0] = '\0'; /* Handle truncation */
|
||||
abort(); /* buffer not large enough */
|
||||
}
|
||||
|
||||
return (int)written;
|
||||
|
Loading…
x
Reference in New Issue
Block a user