Compare commits

..

2 Commits

Author SHA1 Message Date
Bananymous 8834241417 LibC: Fix scanf %n modifier
Old code was always returning off by one
2025-04-22 09:55:38 +03:00
Bananymous 96740d6be4 LibC: Make `inet_addr` spec compliant
I was not doing any error checking, basically i validated anything that
started with atleast a single digit.
2025-04-22 09:40:46 +03:00
2 changed files with 17 additions and 5 deletions

View File

@ -26,10 +26,22 @@ uint16_t ntohs(uint16_t netshort)
in_addr_t inet_addr(const char* cp) in_addr_t inet_addr(const char* cp)
{ {
uint32_t a = 0, b = 0, c = 0, d = 0; uint32_t a, b, c, d, n;
int ret = sscanf(cp, "%u.%u.%u.%u", &a, &b, &c, &d); const int ret = sscanf(cp, "%i%n.%i%n.%i%n.%i%n",
if (ret < 1 || ret > 4) &a, &n, &b, &n, &c, &n, &d, &n
return (in_addr_t)(-1); );
if (ret < 1 || ret > 4 || cp[n] != '\0')
return INADDR_NONE;
if (ret == 1 && (a > 0xFFFFFFFF))
return INADDR_NONE;
if (ret == 2 && (a > 0xFF || b > 0xFFFFFF))
return INADDR_NONE;
if (ret == 3 && (a > 0xFF || b > 0xFF || c > 0xFFFF))
return INADDR_NONE;
if (ret == 4 && (a > 0xFF || b > 0xFF || c > 0xFF || d > 0xFF))
return INADDR_NONE;
uint32_t result = 0; uint32_t result = 0;
result |= (ret == 1) ? a : a << 24; result |= (ret == 1) ? a : a << 24;
result |= (ret == 2) ? b : b << 16; result |= (ret == 2) ? b : b << 16;

View File

@ -596,7 +596,7 @@ int scanf_impl(const char* format, va_list arguments, int (*__getc_fun)(bool adv
} }
case 'n': case 'n':
if (!conversion.suppress) if (!conversion.suppress)
*va_arg(arguments, int*) = nread - (in != NONE); *va_arg(arguments, int*) = nread;
conversion.suppress = true; // Dont count this as conversion conversion.suppress = true; // Dont count this as conversion
result = ConversionResult::SUCCESS; result = ConversionResult::SUCCESS;
break; break;