Loading extra/comp_err.c +120 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading
extra/comp_err.c +120 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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 Loading