From: Hugo Villeneuve Date: Sun, 16 Feb 2014 06:51:47 +0000 (-0500) Subject: Add proper error checking in asciihex2int functions X-Git-Tag: v2.0.1~4 X-Git-Url: http://gitweb.hugovil.com/?p=emu8051.git;a=commitdiff_plain;h=ab28e54867f17238e2b70900d21692f95945a02b Add proper error checking in asciihex2int functions --- diff --git a/src/cli/scanner.l b/src/cli/scanner.l index 1ef440d..919d71e 100644 --- a/src/cli/scanner.l +++ b/src/cli/scanner.l @@ -17,9 +17,26 @@ hextail ({digit}|{alpha}){1,8} hex1 0[xX]{hextail} hex2 ${hextail} + %% -{hex1} { yylval.number = asciihex2int(yytext); return NUMBER; } -{hex2} { yylval.number = asciihex2int(&yytext[1]); return NUMBER; } +{hex1} { + /* + * No need to check return value of asciihex2int, because lex + * always passes a valid ASCII hex string. + */ + yylval.number = asciihex2int(&yytext[2]); /* Skip "0x" prefix */ + return NUMBER; + } +{hex2} { + /* + * No need to check return value of asciihex2int, because lex + * always passes a valid ASCII hex string. + */ + yylval.number = asciihex2int(&yytext[1]); /* Skip "$" prefix */ + return NUMBER; + } + + [0-9]+ { yylval.number = atoi(yytext); return NUMBER; } [h?] return TOK_HELP; sb return TOK_SB; diff --git a/src/common/hexfile.c b/src/common/hexfile.c index ee0c745..b9aff06 100644 --- a/src/common/hexfile.c +++ b/src/common/hexfile.c @@ -29,6 +29,12 @@ static int asciihex2int_error; +int +asciihex2int_get_error(void) +{ + return asciihex2int_error; +} + /* Convert integer to ASCII hex string. */ void int2asciihex(int val, char *str, int width) @@ -43,35 +49,24 @@ int2asciihex(int val, char *str, int width) sprintf(str , "Err"); } -/* Convert ASCII hex string to integer. */ -int -asciihex2int(char *str) -{ - int val; - int rc; - - rc = sscanf(str, "%X", &val); - - if (rc == 0) { - log_err("ASCII to hex conversion failure"); - asciihex2int_error = true; - } - - return val; -} - -/* Convert an ascii string to an hexadecimal number. */ +/* + * Convert ASCII string in hexadecimal notation to integer, up to length + * characters. + * The string contains only [0-9] and [a-f] characters (no "0x" prefix). + */ static unsigned int -asciihex2int_len(char *istring, int length) +asciihex2int_len(char *str, int length) { unsigned int result = 0; int i, ascii_code; - if (!length || (length > (int) strlen(istring))) - length = strlen(istring); + asciihex2int_error = false; + + if (!length || (length > (int) strlen(str))) + length = strlen(str); for (i = 0; i < length; i++) { - ascii_code = istring[i]; + ascii_code = str[i]; if (ascii_code > 0x39) ascii_code &= 0xDF; @@ -86,11 +81,23 @@ asciihex2int_len(char *istring, int length) } else { log_err("ASCII to hex conversion failure"); asciihex2int_error = true; + return 0; } } return result; } +/* + * Convert ASCII string in hexadecimal notation to integer, up to \0 end character. + * The string must not contain prefix "0x", only [0-9] and [a-f] characters. + */ +unsigned int +asciihex2int(char *str) +{ + /* Set length to zero to use full length of string. */ + return asciihex2int_len(str, 0); +} + /* * Return value: * true: success diff --git a/src/common/hexfile.h b/src/common/hexfile.h index f9a258b..d130e1c 100644 --- a/src/common/hexfile.h +++ b/src/common/hexfile.h @@ -10,10 +10,13 @@ #ifndef HEXFILE_H #define HEXFILE_H 1 +int +asciihex2int_get_error(void); + void int2asciihex(int val, char *str, int width); -int +unsigned int asciihex2int(char *str); int diff --git a/src/gtk/memwin.c b/src/gtk/memwin.c index 2ea618a..96be0b5 100644 --- a/src/gtk/memwin.c +++ b/src/gtk/memwin.c @@ -104,6 +104,8 @@ memwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, /* Get base address. */ gtk_tree_model_get(model, &iter, COL_ADDRESS, &str, -1); + + /* No need to check error, has already been validated. */ address = asciihex2int(str); /* Convert column number (1, 2, 3...) to index (0, 1, 2...) */ @@ -115,9 +117,12 @@ memwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, /* Convert new value (asciihex) to integer. */ new = asciihex2int(new_str); - if ((new < 0) || (new > 255)) { - log_info(" new value: out of range"); - new = old; /* Put back old value... */ + if (asciihex2int_get_error()) { + log_warn(" new value: invalid"); + return; + } else if ((new < 0) || (new > 255)) { + log_warn(" new value: out of range"); + return; } else { log_info(" new value: $%02X", new); } diff --git a/src/gtk/pgmwin.c b/src/gtk/pgmwin.c index 4c35d7f..d1ad010 100644 --- a/src/gtk/pgmwin.c +++ b/src/gtk/pgmwin.c @@ -134,6 +134,7 @@ pgmwin_sel_changed_event(GtkWidget *widget, GdkEvent *event, gpointer data) gtk_tree_model_get(model, &iter, COL_ADDR, &str_addr, -1); /* Convert hex address in ASCII to integer. */ + /* No need to check error, has already been validated. */ val = asciihex2int(str_addr); log_debug(" row address is: $%04X", val); diff --git a/src/gtk/pswwin.c b/src/gtk/pswwin.c index e678abf..f0badda 100644 --- a/src/gtk/pswwin.c +++ b/src/gtk/pswwin.c @@ -110,9 +110,12 @@ pswwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, /* Convert new value (asciihex) to integer. */ new = asciihex2int(new_str); - if ((new != 0) && (new != 1)) { - log_info(" new value: out of range"); - new = old; /* Put back old value... */ + if (asciihex2int_get_error()) { + log_warn(" new value: invalid"); + return; + } else if ((new != 0) && (new != 1)) { + log_warn(" new value: out of range"); + return; } else { log_info(" new value: %d", new); } diff --git a/src/gtk/regwin.c b/src/gtk/regwin.c index 2358685..d3fcb8d 100644 --- a/src/gtk/regwin.c +++ b/src/gtk/regwin.c @@ -88,10 +88,16 @@ regwin_cell_edited(GtkCellRendererText *cell, gchar *path_string, /* Read current (old) value. */ gtk_tree_model_get(model, &iter, COL_VAL, &str, -1); + /* No need to check error, has already been validated. */ old = asciihex2int(str); log_info(" old value: $%04X", old); new = asciihex2int(new_str); + if (asciihex2int_get_error()) { + log_warn(" new value: invalid"); + return; + } + log_info(" new value: $%04X", new); /* Store new value in emulator register (if in range). */