diff options
author | unknown <msvensson@pilot.mysql.com> | 2007-02-14 19:34:22 +0100 |
---|---|---|
committer | unknown <msvensson@pilot.mysql.com> | 2007-02-14 19:34:22 +0100 |
commit | 84eaebd4ee15e307a5684f3470a0bc024f015ff8 (patch) | |
tree | fbbf71c12a879aa742e2606390062a6affa7766e /extra/comp_err.c | |
parent | 581db6c18a7a7e566b489509cde5d7d0533f1d3f (diff) | |
parent | 7ca99d797dec77410e04548b29e502c68033d51e (diff) | |
download | mariadb-git-84eaebd4ee15e307a5684f3470a0bc024f015ff8.tar.gz |
Merge pilot.mysql.com:/home/msvensson/mysql/comp_err_checksum/my50-comp_err_checksum
into pilot.mysql.com:/home/msvensson/mysql/comp_err_checksum/my51-comp_err_checksum
extra/comp_err.c:
Auto merged
sql/share/errmsg.txt:
Dont merge errmsg.txt
Diffstat (limited to 'extra/comp_err.c')
-rw-r--r-- | extra/comp_err.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/extra/comp_err.c b/extra/comp_err.c index 00aab96454e..85d1c932d9b 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -132,6 +132,8 @@ static struct message *parse_message_string(struct message *new_message, char *str); static struct message *find_message(struct errors *err, const char *lang, my_bool no_default); +static int check_message_format(struct errors *err, + const char* mess); static int parse_input_file(const char *file_name, struct errors **top_error, struct languages **top_language); static int get_options(int *argc, char ***argv); @@ -458,6 +460,13 @@ static int parse_input_file(const char *file_name, struct errors **top_error, current_error->er_name, current_message.lang_short_name); DBUG_RETURN(0); } + if (check_message_format(current_error, current_message.text)) + { + fprintf(stderr, "Wrong formatspecifier of error message string" + " for error '%s' in language '%s'\n", + current_error->er_name, current_message.lang_short_name); + DBUG_RETURN(0); + } if (insert_dynamic(¤t_error->msg, (byte *) & current_message)) DBUG_RETURN(0); continue; @@ -599,6 +608,117 @@ static struct message *find_message(struct errors *err, const char *lang, } + +/* + Check message format specifiers against error message for + previous language + + SYNOPSIS + checksum_format_specifier() + msg String for which to generate checksum + for the format specifiers + + RETURN VALUE + Returns the checksum for all the characters of the + format specifiers + + Ex. + "text '%-64.s' text part 2 %d'" + ^^^^^^ ^^ + characters will be xored to form checksum + + NOTE: + Does not support format specifiers with positional args + like "%2$s" but that is not yet supported by my_vsnprintf + either. +*/ + +static char checksum_format_specifier(const char* msg) +{ + char chksum= 0; + const char* p= msg; + int is_format_specifier= 0; + int num_format_specifiers= 0; + while (*p) + { + + if (*p == '%') + { + is_format_specifier= 1; /* Entering format specifier */ + num_format_specifiers++; + } + + if (is_format_specifier) + { + chksum^= *p; + switch(*p) + { + case 'd': + case 'u': + case 'x': + case 's': + is_format_specifier= 0; /* Not in format specifier anymore */ + break; + + default: + break; + } + } + + p++; + } + + if (is_format_specifier) + { + /* Still inside a format specifier after end of string */ + + fprintf(stderr, "Still inside formatspecifier after end of string" + " in'%s'\n", msg); + DBUG_ASSERT(is_format_specifier==0); + } + + /* Add number of format specifiers to checksum as extra safeguard */ + chksum+= num_format_specifiers; + + return chksum; +} + + +/* + Check message format specifiers against error message for + previous language + + SYNOPSIS + check_message_format() + err Error to check message for + mess Message to check + + RETURN VALUE + Returns 0 if no previous error message or message format is ok +*/ +static int check_message_format(struct errors *err, + const char* mess) +{ + struct message *first; + DBUG_ENTER("check_message_format"); + + /* Get first message(if any) */ + if ((err->msg).elements == 0) + DBUG_RETURN(0); /* No previous message to compare against */ + + first= dynamic_element(&err->msg, 0, struct message*); + DBUG_ASSERT(first != NULL); + + if (checksum_format_specifier(first->text) != + checksum_format_specifier(mess)) + { + /* Check sum of format specifiers failed, they should be equal */ + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + /* Skips spaces and or tabs till the beginning of the next word Returns pointer to the beginning of the first character of the word |