summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <anozdrin/alik@quad.opbmk>2008-03-28 18:10:04 +0300
committerunknown <anozdrin/alik@quad.opbmk>2008-03-28 18:10:04 +0300
commitfba9e7c878359b0808e0f656d72aceedf34f0f56 (patch)
treedc8481ecdd397cf4753a4fb4ae0b826a319ed232
parent1abfb6e040c7c3b9b157d213cc4e46af3773ce20 (diff)
downloadmariadb-git-fba9e7c878359b0808e0f656d72aceedf34f0f56.tar.gz
A patch for Bug#34820: log_output can be set to illegal value.
We have "set" variables, which can accept empty values (like sql_mode), and which can not (like log_output). The problem was that the code does not distinguish them and allow empty values for every set variable. The fix is to introduce an attribute of a set variable telling whether it can accept empty values. mysql-test/r/variables.result: Update result file. mysql-test/t/variables.test: A test case for Bug#34820: log_output can be set to illegal value. sql/set_var.cc: Don't allow empty values if it is prohibitted. sql/set_var.h: Add a flag (m_allow_empty_value) telling if an empty value is acceptable for this variable.
-rw-r--r--mysql-test/r/variables.result10
-rw-r--r--mysql-test/t/variables.test17
-rw-r--r--sql/set_var.cc25
-rw-r--r--sql/set_var.h18
4 files changed, 63 insertions, 7 deletions
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index e5c3c860c93..3f66599751d 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1014,3 +1014,13 @@ Variable_name='table_lock_wait_timeout';
Variable_name Value
table_definition_cache #
table_lock_wait_timeout #
+
+# --
+# -- Bug#34820: log_output can be set to illegal value.
+# --
+SET GLOBAL log_output = '';
+ERROR 42000: Variable 'log_output' can't be set to the value of ''
+SET GLOBAL log_output = 0;
+ERROR 42000: Variable 'log_output' can't be set to the value of '0'
+
+# -- End of Bug#34820.
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 51f8d6db1db..221f46605cd 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -778,3 +778,20 @@ set global thread_cache_size =@my_thread_cache_size;
--replace_column 2 #
show global variables where Variable_name='table_definition_cache' or
Variable_name='table_lock_wait_timeout';
+
+###########################################################################
+
+--echo
+--echo # --
+--echo # -- Bug#34820: log_output can be set to illegal value.
+--echo # --
+
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL log_output = '';
+
+--error ER_WRONG_VALUE_FOR_VAR
+SET GLOBAL log_output = 0;
+
+--echo
+--echo # -- End of Bug#34820.
+
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 46a64b1a87c..6b07d81125a 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1664,6 +1664,14 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
strmov(buff, "NULL");
goto err;
}
+
+ if (!m_allow_empty_value &&
+ res->length() == 0)
+ {
+ buff[0]= 0;
+ goto err;
+ }
+
var->save_result.ulong_value= ((ulong)
find_set(enum_names, res->c_ptr(),
res->length(),
@@ -1679,10 +1687,19 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
else
{
ulonglong tmp= var->value->val_int();
- /*
- For when the enum is made to contain 64 elements, as 1ULL<<64 is
- undefined, we guard with a "count<64" test.
- */
+
+ if (!m_allow_empty_value &&
+ tmp == 0)
+ {
+ buff[0]= '0';
+ buff[1]= 0;
+ goto err;
+ }
+
+ /*
+ For when the enum is made to contain 64 elements, as 1ULL<<64 is
+ undefined, we guard with a "count<64" test.
+ */
if (unlikely((tmp >= ((ULL(1)) << enum_names->count)) &&
(enum_names->count < 64)))
{
diff --git a/sql/set_var.h b/sql/set_var.h
index b33a3a968bb..c4fc13f1321 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -74,7 +74,8 @@ public:
sys_var(const char *name_arg, sys_after_update_func func= NULL,
Binlog_status_enum binlog_status_arg= NOT_IN_BINLOG)
:name(name_arg), after_update(func), no_support_one_shot(1),
- binlog_status(binlog_status_arg)
+ binlog_status(binlog_status_arg),
+ m_allow_empty_value(TRUE)
{}
virtual ~sys_var() {}
void chain_sys_var(sys_var_chain *chain_arg)
@@ -109,8 +110,16 @@ public:
virtual bool is_readonly() const { return 0; }
virtual sys_var_pluginvar *cast_pluginvar() { return 0; }
+protected:
+ void set_allow_empty_value(bool allow_empty_value)
+ {
+ m_allow_empty_value= allow_empty_value;
+ }
+
private:
const Binlog_status_enum binlog_status;
+
+ bool m_allow_empty_value;
};
@@ -878,8 +887,11 @@ public:
sys_var_log_output(sys_var_chain *chain, const char *name_arg, ulong *value_arg,
TYPELIB *typelib, sys_after_update_func func)
:sys_var(name_arg,func), value(value_arg), enum_names(typelib)
- { chain_sys_var(chain); }
- bool check(THD *thd, set_var *var)
+ {
+ chain_sys_var(chain);
+ set_allow_empty_value(FALSE);
+ }
+ virtual bool check(THD *thd, set_var *var)
{
return check_set(thd, var, enum_names);
}