[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1 2/2] libc: Überarbeiten des Überlaufverhalten von scanf



From: Nico Mayer <mayerNico@xxxxxxxxxx>

! Die bisherige Implementierung der Scanf-Funktion verwendet für das
  Einlesen der Zahlen ausschließlich die Funktion strtoull. Hierdurch verhält
  sich die Scanf-Funktion bei Überläufen bzw. Unterläufen bei verschiedenen
  Datentypen falsch. Mit diesem Commit wählt jetzt die Scanf-Funktion
  für den jeweiligen Datentyp die passende strtoxxx-Funktion aus.

Signed-off-by: Nico Mayer <mayerNico@xxxxxxxxxx>
---
 src/modules/lib/stdlibc/scanf.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/modules/lib/stdlibc/scanf.c b/src/modules/lib/stdlibc/scanf.c
index 0f978606..6d288e36 100644
--- a/src/modules/lib/stdlibc/scanf.c
+++ b/src/modules/lib/stdlibc/scanf.c
@@ -33,6 +33,7 @@
 #include <stddef.h>
 #include <string.h>
 #include <ctype.h>
+#include <stdbool.h>
 
 typedef int (*jscanf_getc)(void* state);
 typedef void (*jscanf_ungetc)(void* state, char c);
@@ -185,6 +186,7 @@ static int jscanf(const char* fmt, va_list ap,
     int c;
     char* endptr;
     uint64_t value;
+    bool is_unsigned = false;
 
     // 64 Bit oktal = 22 Zeichen, führende 0, Vorzeichen und \0
     char buf[25];
@@ -282,22 +284,30 @@ static int jscanf(const char* fmt, va_list ap,
                     // %p - Pointer (strtoul mit Basis 16)
                     case 'i':
                         base = 0;
+                        is_unsigned = false;
                         goto convert_number;
                     case 'o':
                         base = 8;
+                        is_unsigned = true;
                         goto convert_number;
                     case 'x':
                     case 'X':
                         base = 16;
+                        is_unsigned = true;
                         goto convert_number;
                     case 'p':
                         base = 16;
                         size = sizeof(void*);
                         len = 0;
+                        is_unsigned = true;
                         goto convert_number;
                     case 'd':
+                        base = 10;
+                        is_unsigned = false;
+                        goto convert_number;
                     case 'u':
                         base = 10;
+                        is_unsigned = true;
                     convert_number:
                         if (len == 0 || len >= sizeof(buf)) {
                             len = sizeof(buf) - 1;
@@ -305,7 +315,21 @@ static int jscanf(const char* fmt, va_list ap,
                         len = jscanf_read_number(buf, len, jgetc, jungetc,
                             state, base, &eof);
 
-                        value = strtoull(buf, &endptr, base);
+                        // Auswählen der richtigen strtoxxx-Funktion
+                        if (is_unsigned) {
+                            if (size == sizeof(int)) {
+                                value = strtoul(buf, &endptr, base);
+                            } else {
+                                value = strtoull(buf, &endptr, base);
+                            }
+                        } else {
+                            if (size == sizeof(int)) {
+                                value = strtol(buf, &endptr, base);
+                            } else {
+                                value = strtoll(buf, &endptr, base);
+                            }
+                        }
+
                         if ((endptr != buf + len) || (len == 0)) {
                             if ((len == 0) && eof) {
                                 goto input_error;
-- 
2.29.2