Bug #108320 my_error_register doesn't work as expected

Submitted: 29 Aug 2022 14:26 Modified: 1 Sep 2022 7:27
Reporter: ashe sun (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Errors Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any

[29 Aug 2022 14:26] ashe sun
Description:
No overlapping with previously registered error numbers is allowed.

There are some problems with the detection logic of the func my_error_register, overlap may not be detected correctly.

  3   /* Search for the right position in the list. */
  2   for (search_meh_pp = &my_errmsgs_list; *search_meh_pp;
  1        search_meh_pp = &(*search_meh_pp)->meh_next) {
347     if ((*search_meh_pp)->meh_last > first) break;
  1   }
  2
  3   /* Error numbers must be unique. No overlapping is allowed. */
  4   if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last)) {
  5     my_free(meh_p);
  6     return 1;
  7   }

How to repeat:
I constructed an overlapping scenario, just add this codes to the end of  share/messages_to_clients.txt, ER_SUNASHE_2 and ER_SUNASHE_3 are going to overlap.

 +  start-error-number 6000
 +
 +  ER_SUNASHE_1
 +    eng "sunashe error1."
 +
 +  ER_SUNASHE_2
 +    eng "sunashe error2."
 +
 +  start-error-number 6001
 +
 +  ER_SUNASHE_3
 +    eng "sunashe error3."
 +
 +  ER_SUNASHE_4
 +    eng "sunashe error4."

You can see these new error numbers in the generated header file(include/mysqld_error.h) after compiling, as shown below:

   5 #define WARN_UNSUPPORTED_ACL_TABLES_READ 4009
   4 #define ER_BINLOG_UNSAFE_ACL_TABLE_READ_IN_DML_DDL 4010
   3 #define ER_SUNASHE_1 6000
   2 #define ER_SUNASHE_2 6001
   1 #define ER_SUNASHE_3 6001
1661 #define ER_SUNASHE_4 6002

my_error_register does not detect this error when starting mysqld

Suggested fix:
diff --git a/mysys/my_error.cc b/mysys/my_error.cc
index 5ff76f1c7b9..476772608a2 100644
--- a/mysys/my_error.cc
+++ b/mysys/my_error.cc
@@ -344,7 +344,7 @@ int my_error_register(const char *(*get_errmsg)(int), int first, int last) {
   /* Search for the right position in the list. */
   for (search_meh_pp = &my_errmsgs_list; *search_meh_pp;
        search_meh_pp = &(*search_meh_pp)->meh_next) {
-    if ((*search_meh_pp)->meh_last > first) break;
+    if ((*search_meh_pp)->meh_last >= first) break;
   }

   /* Error numbers must be unique. No overlapping is allowed. */
[1 Sep 2022 7:27] MySQL Verification Team
Hello ashe sun,

Thank you for the report and feedback.

regards,
Umesh

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.048 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.