diff options
author | msvensson@pilot.blaudden <> | 2007-02-22 16:41:51 +0100 |
---|---|---|
committer | msvensson@pilot.blaudden <> | 2007-02-22 16:41:51 +0100 |
commit | 05305f462b4c6910b8f52b4f9d826e44fa4eaeae (patch) | |
tree | 67aeec019ed546292ccbda94a06fcc55df4d69cc /extra | |
parent | 9e9dd4327c76d10a07783f790f65cd4487da264d (diff) | |
download | mariadb-git-05305f462b4c6910b8f52b4f9d826e44fa4eaeae.tar.gz |
Bug #26571 Different format specifiers in errmsg.txt
- Add check of format specifiers in error message strings
- Update error message text accordingly to be equal between all translations
Diffstat (limited to 'extra')
-rw-r--r-- | extra/Makefile.am | 3 | ||||
-rw-r--r-- | extra/comp_err.c | 119 |
2 files changed, 121 insertions, 1 deletions
diff --git a/extra/Makefile.am b/extra/Makefile.am index 1448962e427..6eac67e2979 100644 --- a/extra/Makefile.am +++ b/extra/Makefile.am @@ -16,7 +16,8 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ @ndbcluster_includes@ -I$(top_srcdir)/sql LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \ - ../dbug/libdbug.a ../strings/libmystrings.a + ../dbug/libdbug.a ../strings/libmystrings.a \ + $(ZLIB_LIBS) BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \ $(top_builddir)/include/sql_state.h \ $(top_builddir)/include/mysqld_ername.h diff --git a/extra/comp_err.c b/extra/comp_err.c index df6df1678a6..4a578a5f0db 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,116 @@ 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; + const char* start= 0; + int num_format_specifiers= 0; + while (*p) + { + + if (*p == '%') + { + start= p+1; /* Entering format specifier */ + num_format_specifiers++; + } + else if (start) + { + switch(*p) + { + case 'd': + case 'u': + case 'x': + case 's': + chksum= my_checksum(chksum, start, p-start); + start= 0; /* Not in format specifier anymore */ + break; + + default: + break; + } + } + + p++; + } + + if (start) + { + /* Still inside a format specifier after end of string */ + + fprintf(stderr, "Still inside formatspecifier after end of string" + " in'%s'\n", msg); + DBUG_ASSERT(start==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 |