Fix issue with different decimal separators

An issue was discovered in the ZFSonLinux driver wherein on a system
set to have a locale where the decimal separator is not a period but
rather a comma the method translate_string_size_to_float() would fail
because it's regex to find sizes in strings did not account for any
other decimal separators other than periods.

This fix updates the regular expression to accept either a period or
a comma as a decimal separator in a size string.

Many thanks to Dr. Clemens Hardewig for reporting the original bug
and providing an updated regular expression.

Change-Id: I15da4aaff90814eed03816db013d6acc89ba2ee8
Closes-Bug: #1714691
This commit is contained in:
Dustin Schoenbrun 2017-10-25 18:00:50 -04:00
parent c86e7658af
commit 8800e54f77
3 changed files with 23 additions and 3 deletions

View File

@ -116,19 +116,25 @@ class GenericUtilsTestCase(test.TestCase):
@ddt.data( @ddt.data(
(("3G", "G"), 3.0), (("3G", "G"), 3.0),
(("4.1G", "G"), 4.1), (("4.1G", "G"), 4.1),
(("4,1G", "G"), 4.1),
(("5.23G", "G"), 5.23), (("5.23G", "G"), 5.23),
(("5,23G", "G"), 5.23),
(("9728M", "G"), 9.5), (("9728M", "G"), 9.5),
(("8192K", "G"), 0.0078125), (("8192K", "G"), 0.0078125),
(("2T", "G"), 2048.0), (("2T", "G"), 2048.0),
(("2.1T", "G"), 2150.4), (("2.1T", "G"), 2150.4),
(("2,1T", "G"), 2150.4),
(("3P", "G"), 3145728.0), (("3P", "G"), 3145728.0),
(("3.4P", "G"), 3565158.4), (("3.4P", "G"), 3565158.4),
(("3,4P", "G"), 3565158.4),
(("9728M", "M"), 9728.0), (("9728M", "M"), 9728.0),
(("9728.2381T", "T"), 9728.2381), (("9728.2381T", "T"), 9728.2381),
(("9728,2381T", "T"), 9728.2381),
(("0", "G"), 0.0), (("0", "G"), 0.0),
(("512", "M"), 0.00048828125), (("512", "M"), 0.00048828125),
(("2097152.", "M"), 2.0), (("2097152.", "M"), 2.0),
((".1024", "K"), 0.0001), ((".1024", "K"), 0.0001),
((",1024", "K"), 0.0001),
(("2048G", "T"), 2.0), (("2048G", "T"), 2.0),
(("65536G", "P"), 0.0625), (("65536G", "P"), 0.0625),
) )
@ -145,6 +151,14 @@ class GenericUtilsTestCase(test.TestCase):
("1KM", "G"), ("1KM", "G"),
("K1M", "G"), ("K1M", "G"),
("M1K", "G"), ("M1K", "G"),
("1.2fake", "G"),
("1,2fake", "G"),
("2.2GG", "G"),
("1.1KM", "G"),
("K2.2M", "G"),
("K2,2M", "G"),
("M2.2K", "G"),
("M2,2K", "G"),
("", "G"), ("", "G"),
(23, "G"), (23, "G"),
(23.0, "G"), (23.0, "G"),

View File

@ -609,14 +609,15 @@ def translate_string_size_to_float(string, multiplier='G'):
} }
) )
try: try:
value = float(string) / 1024.0 value = float(string.replace(",", ".")) / 1024.0
value = value / mapping[multiplier] value = value / mapping[multiplier]
return value return value
except (ValueError, TypeError): except (ValueError, TypeError):
matched = re.match( matched = re.match(
r"^(\d+\.*\d*)([%s])$" % ','.join(multipliers), string) r"^(\d*[.,]*\d*)([%s])$" % ''.join(multipliers), string)
if matched: if matched:
value = float(matched.groups()[0]) # The replace() is needed in case decimal separator is a comma
value = float(matched.groups()[0].replace(",", "."))
multiplier = mapping[matched.groups()[1]] / mapping[multiplier] multiplier = mapping[matched.groups()[1]] / mapping[multiplier]
return value * multiplier return value * multiplier

View File

@ -0,0 +1,5 @@
---
fixes:
- Fixed issue where locales other than POSIX and en_US.UTF-8 might
cause the translate_string_size_to_float method to fail on a
comma decimal separator instead of a period decimal separator.