Bug #68055 Indeterminate behavior due to empty option values
Submitted: 9 Jan 2013 9:03 Modified: 6 May 2014 14:11
Reporter: Tianyin Xu Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Options Severity:S2 (Serious)
Version:mysql-5.5.29 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution
Triage: Needs Triage: D3 (Medium)

[9 Jan 2013 9:03] Tianyin Xu
Description:
Hi, 

The current configuration parser allows empty value as the option value. However, the empty value causes inconsistent and indeterminate behavior which might confuse users.

=============================
Symptom
=============================

1. For numeric options including INT, UINT, LONG, ULONG, the parser translate the empty value to 0, because of using "strtoll()" call in "eval_num_suffix()", as follows,

/* mysys/my_getopt.c */
864   num= strtoll(argument, &endchar, 10);

When argument is "", the returned num will be 0.

For example, start mysqld with the empty value of "query_cache_limit"

$ mysqld --query_cache_limit=

Retrieve the system value:

$ mysqld
mysql> SHOW GLOBAL VARIABLES LIKE 'query\_cache\_limit';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| query_cache_limit | 0     |
+-------------------+-------+
1 row in set (0.00 sec)

-----------------------------

2. For boolean value, the empty value is rejected and set to "OFF"

$ mysqld --performance-schema=

130109  0:27:31 [Warning] Buffered warning: option 'performance_schema': boolean value '' wasn't recognized. Set to OFF.

-----------------------------

3. For string value, the results are indeterminate.

3.1

$ mysqld --innodb_data_file_path=
130109  0:31:00 [ERROR] InnoDB: syntax error in innodb_data_file_path
130109  0:31:00 [ERROR] Plugin 'InnoDB' init function returned error.
130109  0:31:00 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
130109  0:31:00 [ERROR] Unknown/unsupported storage engine: InnoDB
130109  0:31:00 [ERROR] Aborting

3.2 

$ mysqld --socket=
130109  0:33:17 InnoDB: The InnoDB memory heap is disabled
130109  0:33:17 InnoDB: Mutexes and rw_locks use GCC atomic builtins
130109  0:33:17 InnoDB: Compressed tables use zlib 1.2.3.4
130109  0:33:17 InnoDB: Initializing buffer pool, size = 8.0M
130109  0:33:17 InnoDB: Completed initialization of buffer pool
130109  0:33:17 InnoDB: highest supported file format is Barracuda.
130109  0:33:17  InnoDB: Waiting for the background threads to start
130109  0:33:18 InnoDB: 1.1.8 started; log sequence number 116061718
130109  0:33:18 [Note] Server hostname (bind-address): '127.0.0.1'; port: 3306
130109  0:33:18 [Note]   - '127.0.0.1' resolves to '127.0.0.1';
130109  0:33:18 [Note] Server socket created on IP: '127.0.0.1'.
130109  0:33:18 [Note] Event Scheduler: Loaded 1 event
130109  0:33:18 [Note] bin/mysqld: ready for connections.
Version: '5.5.29-log'  socket: ''  port: 3306  Source distribution

mysql --host=localhost --port=3306
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

=============================
Root Cause
=============================

The root cause is such empty value is never checked in the configuration parser, and it goes through all the checking and finally get used. 

How to repeat:
Described in the "Description" section.

Suggested fix:
I suggest to check it in the very beginning in setval() in my_getopt.c. See the patch attached. 

The behavior is to ignore the input and print out an error message, while keeping the option value unchanged. In this way, it has no side effect.

The patch is tested.

--- mysql-5.5.29/mysys/my_getopt.c    2012-08-29 01:50:46.000000000 -0700
+++ mysql-5.5.29/mysys/my_getopt.c    2013-01-09 00:57:10.020208478 -0800
@@ -642,6 +642,13 @@
 
   if (!argument)
     argument= enabled_my_option;
+  
+  if(strlen(argument) == 0) {
+    my_getopt_error_reporter(ERROR_LEVEL,
+                             "%s: Empty value of '%s' is specified. Keep the previous value unchanged",
+                             my_progname, opts->name);  
+    return 0;
+  }
 
   if (value)
   {
[9 Jan 2013 9:05] Tianyin Xu
Patch to ignore the empty value in the beginning of the configuration parser

Attachment: my.my_getopt.patch (text/x-diff), 499 bytes.

[11 Jan 2013 13:18] Sveta Smirnova
Thank you for the report.

Verified as described.
[6 May 2014 14:11] Paul Dubois
Posted by developer:
 
Noted in 5.7.5 changelog.

The empty string provided for numeric or enumeration options (for
example, --port="") produced inconsistent or confusing behavior. Such
empty option values now are rejected with an error.