diff options
author | unknown <msvensson@pilot.blaudden> | 2007-02-22 19:16:18 +0100 |
---|---|---|
committer | unknown <msvensson@pilot.blaudden> | 2007-02-22 19:16:18 +0100 |
commit | 2b4851f0cf2d39fe2b476aa298f43ce8fb21ea0a (patch) | |
tree | ccec0cda9a4cc5eabb1a36f0bf0001a1688d58a3 /extra | |
parent | 59e9be2257b1f22026c3331eb6ad67bc57781096 (diff) | |
parent | bac1c946ceb094552302d86931c54d7679c4caba (diff) | |
download | mariadb-git-2b4851f0cf2d39fe2b476aa298f43ce8fb21ea0a.tar.gz |
Merge bk-internal:/home/bk/mysql-5.0-maint
into pilot.blaudden:/home/msvensson/mysql/comp_err_checksum/my50-comp_err_checksum
sql/share/errmsg.txt:
Auto merged
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 |