summaryrefslogtreecommitdiff
path: root/extra
diff options
context:
space:
mode:
authorunknown <msvensson@pilot.blaudden>2007-02-22 16:41:51 +0100
committerunknown <msvensson@pilot.blaudden>2007-02-22 16:41:51 +0100
commitc36e2c23323fb2d8afe9ac08a08c3fd7ec041886 (patch)
tree67aeec019ed546292ccbda94a06fcc55df4d69cc /extra
parent035062b2a7506bfa159bfc67ed710a19beee2114 (diff)
downloadmariadb-git-c36e2c23323fb2d8afe9ac08a08c3fd7ec041886.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 extra/Makefile.am: comp_err uses my_cheksum, link with zlib extra/comp_err.c: Add check of format specifiers in error message strings sql/share/errmsg.txt: Update error messages after checks --- Remove the newly added space in error message, should not be there
Diffstat (limited to 'extra')
-rw-r--r--extra/Makefile.am3
-rw-r--r--extra/comp_err.c119
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(&current_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