mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
fix(std-io): make uint128 decimal formatting safe (#2924)
* fix(std-io): make uint128 decimal formatting safe and add all-base numeric coverage --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
committed by
GitHub
parent
7665720264
commit
f079fa82b2
@@ -13,8 +13,7 @@ interface Printable
|
||||
fn usz? to_format(Formatter* formatter) @optional;
|
||||
}
|
||||
|
||||
faultdef BUFFER_EXCEEDED, INTERNAL_BUFFER_EXCEEDED, INVALID_FORMAT,
|
||||
NOT_ENOUGH_ARGUMENTS, INVALID_ARGUMENT;
|
||||
faultdef BUFFER_EXCEEDED, INTERNAL_BUFFER_EXCEEDED, INVALID_FORMAT, NOT_ENOUGH_ARGUMENTS, INVALID_ARGUMENT;
|
||||
|
||||
alias OutputFn = fn void?(void* buffer, char c);
|
||||
alias FloatType = double;
|
||||
@@ -34,14 +33,14 @@ macro bool is_struct_with_default_print($Type)
|
||||
*>
|
||||
macro usz? struct_to_format(value, Formatter* f, bool $force_dump)
|
||||
{
|
||||
var $Type = $typeof(value);
|
||||
usz total = f.print("{ ")!;
|
||||
$foreach $i, $member : $Type.membersof:
|
||||
$if $i > 0:
|
||||
total += f.print(", ")!;
|
||||
$endif
|
||||
$if $member.nameof != "":
|
||||
total += f.printf("%s: ", $member.nameof)!;
|
||||
var $Type = $typeof(value);
|
||||
usz total = f.print("{ ")!;
|
||||
$foreach $i, $member : $Type.membersof:
|
||||
$if $i > 0:
|
||||
total += f.print(", ")!;
|
||||
$endif
|
||||
$if $member.nameof != "":
|
||||
total += f.printf("%s: ", $member.nameof)!;
|
||||
$endif
|
||||
$if ($force_dump &&& ($member.typeid.kindof == STRUCT || $member.typeid.kindof == BITSTRUCT)) |||
|
||||
is_struct_with_default_print($member.typeid):
|
||||
@@ -351,12 +350,12 @@ macro usz? @wrap_bad(Formatter* f, #action)
|
||||
switch (err)
|
||||
{
|
||||
case BUFFER_EXCEEDED:
|
||||
case INTERNAL_BUFFER_EXCEEDED:
|
||||
return f.first_err(err)~;
|
||||
default:
|
||||
case INTERNAL_BUFFER_EXCEEDED:
|
||||
return f.first_err(err)~;
|
||||
default:
|
||||
err = f.first_err(INVALID_ARGUMENT);
|
||||
f.out_substr("<INVALID>")!;
|
||||
return err~;
|
||||
f.out_substr("<INVALID>")!;
|
||||
return err~;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
@@ -489,7 +488,7 @@ fn usz? Formatter.vprintf(&self, String format, any[] anys)
|
||||
self.flags.uppercase = true;
|
||||
nextcase;
|
||||
case 'h':
|
||||
char[] out @noinit;
|
||||
char[] out @noinit;
|
||||
switch (current.type)
|
||||
{
|
||||
case char[]:
|
||||
|
||||
@@ -541,7 +541,6 @@ const char[201] DIGIT_PAIRS @private =
|
||||
"08182838485868788898"
|
||||
"09192939495969798999";
|
||||
|
||||
|
||||
fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
|
||||
{
|
||||
char[PRINTF_NTOA_BUFFER_SIZE] buf @noinit;
|
||||
@@ -574,10 +573,10 @@ fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
|
||||
while (value >= 10)
|
||||
{
|
||||
if (len + 1 >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
char digit = (char)(value % 100);
|
||||
char digit = (char)(value % 100U);
|
||||
buf[len:2] = DIGIT_PAIRS[2 * digit:2];
|
||||
len += 2;
|
||||
value /= 100;
|
||||
value /= 100U;
|
||||
}
|
||||
if (value > 0)
|
||||
{
|
||||
@@ -593,16 +592,16 @@ fn usz? Formatter.ntoa(&self, uint128 value, bool negative, uint base) @private
|
||||
value >>= 4;
|
||||
}
|
||||
while (value);
|
||||
case 8:
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0' + (char)value & 0x7;
|
||||
value >>= 3;
|
||||
}
|
||||
while (value);
|
||||
default:
|
||||
unreachable();
|
||||
case 8:
|
||||
do
|
||||
{
|
||||
if (len >= PRINTF_NTOA_BUFFER_SIZE) return INTERNAL_BUFFER_EXCEEDED~;
|
||||
buf[len++] = '0' + (char)value & 0x7;
|
||||
value >>= 3;
|
||||
}
|
||||
while (value);
|
||||
default:
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
return self.ntoa_format((String)buf[:PRINTF_NTOA_BUFFER_SIZE], len, negative, base);
|
||||
@@ -684,9 +683,9 @@ fn usz? Formatter.out_char(&self, any arg) @private
|
||||
usz len = 1;
|
||||
// pre padding
|
||||
if (!self.flags.left)
|
||||
{
|
||||
len += self.pad(' ', self.width, len)!;
|
||||
}
|
||||
{
|
||||
len += self.pad(' ', self.width, len)!;
|
||||
}
|
||||
|
||||
// char output
|
||||
Char32 c = types::any_to_int(arg, uint) ?? 0xFFFD;
|
||||
@@ -708,8 +707,8 @@ fn usz? Formatter.out_char(&self, any arg) @private
|
||||
self.out((char)(0x80 | (c & 0x3F)))!;
|
||||
}
|
||||
if (self.flags.left)
|
||||
{
|
||||
len += self.pad(' ', self.width, len)!;
|
||||
{
|
||||
len += self.pad(' ', self.width, len)!;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user