From f533d88c6ff6a765fa357e88943bd779fb5d6d60 Mon Sep 17 00:00:00 2001 From: Jinping Han Date: Wed, 13 Feb 2019 10:37:42 -0800 Subject: [PATCH 1/6] Value in quotes in shorthand publish should be evaluated as string type Fixes issue https://github.com/StackStorm/orquesta/issues/130 During `parse_inline_params` is called to parse parameters input, the leading and trailing single/double quotes is removed. Digit and True/False in quotes will be parsed as number and boolean type instead of String after `json.loads()`. Solution: For string in quotes (not includes dictionary `'x=\'{\"a\": 1}\''`), 'json.loads' is not called. --- orquesta/tests/unit/utils/test_parameters.py | 17 +++++++++++++++++ orquesta/utils/parameters.py | 13 ++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/orquesta/tests/unit/utils/test_parameters.py b/orquesta/tests/unit/utils/test_parameters.py index 6d8a3cfd..f9cd35ab 100644 --- a/orquesta/tests/unit/utils/test_parameters.py +++ b/orquesta/tests/unit/utils/test_parameters.py @@ -96,6 +96,23 @@ def test_parse_bool_input(self): for s, d in tests: self.assertListEqual(params.parse_inline_params(s), d) + def test_parse_string_in_quotes_input(self): + tests = [ + ('x="true"', [{'x': "true"}]), + ('y="True"', [{'y': "True"}]), + ('c="TRUE"', [{'c': "TRUE"}]), + ('d="123"', [{'d': '123'}]), + ('e="abcde"', [{'e': 'abcde'}]), + ("x='false'", [{'x': 'false'}]), + ("y='False'", [{'y': 'False'}]), + ("c='FALSE'", [{'c': 'FALSE'}]), + ("d='123'", [{'d': '123'}]), + ("e='abcde'", [{'e': 'abcde'}]), + ] + + for s, d in tests: + self.assertListEqual(params.parse_inline_params(s), d) + def test_parse_other_types(self): self.assertListEqual(params.parse_inline_params(123), []) self.assertListEqual(params.parse_inline_params(True), []) diff --git a/orquesta/utils/parameters.py b/orquesta/utils/parameters.py index 22a9c54a..f935cb6d 100644 --- a/orquesta/utils/parameters.py +++ b/orquesta/utils/parameters.py @@ -53,6 +53,9 @@ def parse_inline_params(s, preserve_order=True): # Remove leading and trailing whitespaces. v = v.strip() + quotes_in_param = bool(re.findall(REGEX_VALUE_IN_QUOTES, v) or + re.findall(REGEX_VALUE_IN_APOSTROPHES, v)) + # Remove leading and trailing double quotes. v = re.sub('^"', '', v) v = re.sub('"$', '', v) @@ -61,12 +64,16 @@ def parse_inline_params(s, preserve_order=True): v = re.sub("^'", '', v) v = re.sub("'$", '', v) - if v.lower() == 'true' or v.lower() == 'false': - v = v.lower() + curly_brace_in_param = bool(v[0] == '{' and v[len(v) -1] == '}') + quotes_in_string = bool(quotes_in_param and not curly_brace_in_param) + is_bool_value = bool(v.lower() == 'true' or v.lower() == 'false') # Load string into dictionary. try: - v = json.loads(v) + if not quotes_in_string: + if is_bool_value: + v = v.lower() + v = json.loads(v) except Exception: pass From 9a8dccb05a430723aee28b2c1be7c179d9c9cd04 Mon Sep 17 00:00:00 2001 From: jinpingh <31353550+jinpingh@users.noreply.github.com> Date: Wed, 13 Feb 2019 11:51:26 -0800 Subject: [PATCH 2/6] Update parameters.py --- orquesta/utils/parameters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orquesta/utils/parameters.py b/orquesta/utils/parameters.py index f935cb6d..5e56e1d6 100644 --- a/orquesta/utils/parameters.py +++ b/orquesta/utils/parameters.py @@ -64,7 +64,7 @@ def parse_inline_params(s, preserve_order=True): v = re.sub("^'", '', v) v = re.sub("'$", '', v) - curly_brace_in_param = bool(v[0] == '{' and v[len(v) -1] == '}') + curly_brace_in_param = bool(v[0] == '{' and v[len(v) - 1] == '}') quotes_in_string = bool(quotes_in_param and not curly_brace_in_param) is_bool_value = bool(v.lower() == 'true' or v.lower() == 'false') From 199c00afe745374e397ea61f9f626939f57b7ce6 Mon Sep 17 00:00:00 2001 From: Jinping Han Date: Thu, 14 Feb 2019 13:00:26 -0800 Subject: [PATCH 3/6] 1. Add comment why need to check curly brace 2. Handle empty string --- orquesta/tests/unit/utils/test_parameters.py | 1 + orquesta/utils/parameters.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/orquesta/tests/unit/utils/test_parameters.py b/orquesta/tests/unit/utils/test_parameters.py index f9cd35ab..a4be8a0f 100644 --- a/orquesta/tests/unit/utils/test_parameters.py +++ b/orquesta/tests/unit/utils/test_parameters.py @@ -108,6 +108,7 @@ def test_parse_string_in_quotes_input(self): ("c='FALSE'", [{'c': 'FALSE'}]), ("d='123'", [{'d': '123'}]), ("e='abcde'", [{'e': 'abcde'}]), + ("f=''", [{'f': ''}]) ] for s, d in tests: diff --git a/orquesta/utils/parameters.py b/orquesta/utils/parameters.py index 5e56e1d6..a2c59eda 100644 --- a/orquesta/utils/parameters.py +++ b/orquesta/utils/parameters.py @@ -64,8 +64,11 @@ def parse_inline_params(s, preserve_order=True): v = re.sub("^'", '', v) v = re.sub("'$", '', v) - curly_brace_in_param = bool(v[0] == '{' and v[len(v) - 1] == '}') - quotes_in_string = bool(quotes_in_param and not curly_brace_in_param) + quotes_in_string = False + if v != "": + # Check if param is a JSON string becuse it can be handled by json.loads() + curly_brace_in_param = bool(v[0] == '{' and v[-1] == '}') + quotes_in_string = bool(quotes_in_param and not curly_brace_in_param) is_bool_value = bool(v.lower() == 'true' or v.lower() == 'false') # Load string into dictionary. From 63990ae87ce931895daad9295e53df16be7bd5c5 Mon Sep 17 00:00:00 2001 From: Jinping Han Date: Thu, 14 Feb 2019 13:00:26 -0800 Subject: [PATCH 4/6] Handle empty string and add comment for parse 1. Add comment why need to check curly brace 2. Handle empty string --- orquesta/tests/unit/utils/test_parameters.py | 1 + orquesta/utils/parameters.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/orquesta/tests/unit/utils/test_parameters.py b/orquesta/tests/unit/utils/test_parameters.py index f9cd35ab..a4be8a0f 100644 --- a/orquesta/tests/unit/utils/test_parameters.py +++ b/orquesta/tests/unit/utils/test_parameters.py @@ -108,6 +108,7 @@ def test_parse_string_in_quotes_input(self): ("c='FALSE'", [{'c': 'FALSE'}]), ("d='123'", [{'d': '123'}]), ("e='abcde'", [{'e': 'abcde'}]), + ("f=''", [{'f': ''}]) ] for s, d in tests: diff --git a/orquesta/utils/parameters.py b/orquesta/utils/parameters.py index 5e56e1d6..a2c59eda 100644 --- a/orquesta/utils/parameters.py +++ b/orquesta/utils/parameters.py @@ -64,8 +64,11 @@ def parse_inline_params(s, preserve_order=True): v = re.sub("^'", '', v) v = re.sub("'$", '', v) - curly_brace_in_param = bool(v[0] == '{' and v[len(v) - 1] == '}') - quotes_in_string = bool(quotes_in_param and not curly_brace_in_param) + quotes_in_string = False + if v != "": + # Check if param is a JSON string becuse it can be handled by json.loads() + curly_brace_in_param = bool(v[0] == '{' and v[-1] == '}') + quotes_in_string = bool(quotes_in_param and not curly_brace_in_param) is_bool_value = bool(v.lower() == 'true' or v.lower() == 'false') # Load string into dictionary. From 6e1a30e56a4dfad3c2887425c14e2ac869d8c4ce Mon Sep 17 00:00:00 2001 From: Jinping Han Date: Thu, 14 Feb 2019 16:10:07 -0800 Subject: [PATCH 5/6] Add test for double quotes. `('f=""', [{'f': ''}])` Modify test_parameter.py to add test for double quotes with empty string. --- orquesta/tests/unit/utils/test_parameters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/orquesta/tests/unit/utils/test_parameters.py b/orquesta/tests/unit/utils/test_parameters.py index a4be8a0f..b644a7cc 100644 --- a/orquesta/tests/unit/utils/test_parameters.py +++ b/orquesta/tests/unit/utils/test_parameters.py @@ -103,6 +103,7 @@ def test_parse_string_in_quotes_input(self): ('c="TRUE"', [{'c': "TRUE"}]), ('d="123"', [{'d': '123'}]), ('e="abcde"', [{'e': 'abcde'}]), + ('f=""', [{'f': ''}]), ("x='false'", [{'x': 'false'}]), ("y='False'", [{'y': 'False'}]), ("c='FALSE'", [{'c': 'FALSE'}]), From a9279133f995eaa303e09f855cf635af69438ad2 Mon Sep 17 00:00:00 2001 From: Jinping Han Date: Thu, 14 Feb 2019 16:35:23 -0800 Subject: [PATCH 6/6] Remove bool() checking since it is already evaluated to boolean --- orquesta/utils/parameters.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/orquesta/utils/parameters.py b/orquesta/utils/parameters.py index a2c59eda..de7b145f 100644 --- a/orquesta/utils/parameters.py +++ b/orquesta/utils/parameters.py @@ -67,9 +67,9 @@ def parse_inline_params(s, preserve_order=True): quotes_in_string = False if v != "": # Check if param is a JSON string becuse it can be handled by json.loads() - curly_brace_in_param = bool(v[0] == '{' and v[-1] == '}') - quotes_in_string = bool(quotes_in_param and not curly_brace_in_param) - is_bool_value = bool(v.lower() == 'true' or v.lower() == 'false') + curly_brace_in_param = v[0] == '{' and v[-1] == '}' + quotes_in_string = quotes_in_param and not curly_brace_in_param + is_bool_value = v.lower() == 'true' or v.lower() == 'false' # Load string into dictionary. try: