Skip to content

Commit 9e2881d

Browse files
committed
BUG32838010: Fix option files parsing with include directive
This patch fixes the option files parsing when using the include directive in config files with override sections. Example: !include D:\test\base.cnf [mysql] port = 1002 The mysql.port should be 1002. A test was added for regression.
1 parent 0e17805 commit 9e2881d

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ v8.0.26
1616
- WL#14440: Support for authentication_kerberos_client authentication plugin
1717
- WL#14237: Support query attributes
1818
- BUG#32947160: Remove MySQLdb module dependency from Django backend
19+
- BUG#32838010: Fix option files parsing with include directive
1920
- BUG#32789076: MSI is missing required libraries to use auth_ldap_client plugin
2021
- BUG#32778827: Raise an error if the _id is different when replacing a document
2122
- BUG#32740486: Fix typo in docstring

lib/mysql/connector/optionfiles.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2014, 2020, Oracle and/or its affiliates.
1+
# Copyright (c) 2014, 2021, Oracle and/or its affiliates.
22
#
33
# This program is free software; you can redistribute it and/or modify
44
# it under the terms of the GNU General Public License, version 2.0, as
@@ -166,12 +166,14 @@ def _parse_options(self, files):
166166
Raises ValueError if any of the included or file given in arguments
167167
is not readable.
168168
"""
169+
initial_files = files[:]
170+
files = []
169171
index = 0
170172
err_msg = "Option file '{0}' being included again in file '{1}'"
171173

172-
for file_ in files:
174+
for file_ in initial_files:
173175
try:
174-
if file_ in files[index+1:]:
176+
if file_ in initial_files[index+1:]:
175177
raise ValueError("Same option file '{0}' occurring more "
176178
"than once in the list".format(file_))
177179
with open(file_, 'r') as op_file:
@@ -186,18 +188,18 @@ def _parse_options(self, files):
186188
entry, file_))
187189
if (os.path.isfile(entry) and
188190
entry.endswith(self.default_extension)):
189-
files.insert(index+1, entry)
191+
files.append(entry)
190192

191193
elif line.startswith('!include'):
192194
_, filename = line.split(None, 1)
193195
filename = filename.strip()
194196
if filename in files:
195197
raise ValueError(err_msg.format(
196198
filename, file_))
197-
files.insert(index+1, filename)
199+
files.append(filename)
198200

199201
index += 1
200-
202+
files.append(file_)
201203
except (IOError, OSError) as exc:
202204
raise ValueError("Failed reading file '{0}': {1}".format(
203205
file_, str(exc)))
@@ -224,6 +226,10 @@ def read(self, filenames): # pylint: disable=W0221
224226
out_file = io.StringIO()
225227
for line in codecs.open(filename, encoding='utf-8'):
226228
line = line.strip()
229+
# Skip lines that begin with "!includedir" or "!include"
230+
if line.startswith('!include'):
231+
continue
232+
227233
match_obj = self.OPTCRE.match(line)
228234
if not self.SECTCRE.match(line) and match_obj:
229235
optname, delimiter, optval = match_obj.group('option',
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
!include tests/data/option_files/my.cnf
2+
3+
[mysqld]
4+
port=1002

tests/test_optionfiles.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
22
#
33
# This program is free software; you can redistribute it and/or modify
44
# it under the terms of the GNU General Public License, version 2.0, as
@@ -214,3 +214,27 @@ def test_read_option_files(self):
214214
self.assertEqual(exp, result)
215215

216216
self.assertRaises(ValueError, connect, option_files='dummy_file.cnf')
217+
218+
def test_read_option_files_with_include(self):
219+
top_dir = os.path.dirname(os.path.realpath(__file__))
220+
my_cnf_name = 'my.cnf'
221+
my_cnf = os.path.join(self.option_file_dir, my_cnf_name)
222+
my_overwrite = os.path.join(
223+
top_dir,
224+
"..",
225+
self.option_file_dir,
226+
'my_include_override.cnf'
227+
)
228+
229+
result = read_option_files(
230+
option_files=my_overwrite,
231+
option_groups='mysqld'
232+
)
233+
234+
# option in the overwrite file
235+
port_exp = 1002
236+
self.assertEqual(port_exp, result['port'])
237+
238+
# option in the include file
239+
user_exp = 'mysql'
240+
self.assertEqual(user_exp, result['user'])

0 commit comments

Comments
 (0)