Remove format function

The format function allowed too arbitrary access to the values being
formatted, and this behavior caused information leakage in some cases.

Closes-Bug: #2048114
Change-Id: Id7ec5f267314bb7166ca64802ab47d768bb5eb89
This commit is contained in:
Takashi Kajinami 2024-03-12 23:38:54 +09:00
parent 2a159b85ae
commit 83e28324e1
4 changed files with 16 additions and 40 deletions

View File

@ -0,0 +1,12 @@
---
upgrade:
- |
The format YAQL function has been removed, because of its vulnability. See
the security section to find more details.
security:
- |
`<https://bugs.launchpad.net/murano/+bug/2048114>`_: The format YAQL
function has been removed, because it allowed too arbitrary data access
which results in data leak. Users can replace the format function by
``+`` operator and ``str`` YAQL function.

View File

@ -564,38 +564,6 @@ def replace_with_dict(string, str_func, replacements, count=-1):
return string return string
@specs.parameter('__format_string', yaqltypes.String())
@specs.extension_method
def format_(__format_string, *args, **kwargs):
""":yaql:format
Returns a string formatted with positional and keyword arguments.
:signature: string.format([args], {kwargs})
:receiverArg string: input string for formatting. Can be passed only as
first positional argument if used as a function. Can contain literal
text or replacement fields marked by braces {}. Every replacement field
should contain either the numeric index of a positional argument or the
name of a keyword argument
:argType string: string
:arg [args]: values for replacements for numeric markers
:argType [args]: chain of strings
:arg {kwargs}: values for keyword replacements
:argType {kwargs}: chain of key-value arguments, where values are strings
:returnValue: string
.. code::
yaql> "abc{0}ab{1}abc".format(" ", ",")
"abc ab,abc"
yaql> "abc{foo}ab{bar}abc".format(foo => " ", bar => ",")
"abc ab,abc"
yaql> format("abc{0}ab{foo}abc", ' ', foo => ",")
"abc ab,abc"
"""
return __format_string.format(*args, **kwargs)
@specs.parameter('left', yaqltypes.String()) @specs.parameter('left', yaqltypes.String())
@specs.parameter('right', int) @specs.parameter('right', int)
@specs.name('#operator_*') @specs.name('#operator_*')
@ -1045,7 +1013,6 @@ def register(context):
context.register_function(trim_right) context.register_function(trim_right)
context.register_function(replace) context.register_function(replace)
context.register_function(replace_with_dict) context.register_function(replace_with_dict)
context.register_function(format_)
context.register_function(is_empty) context.register_function(is_empty)
context.register_function(string_by_int) context.register_function(string_by_int)
context.register_function(int_by_string) context.register_function(int_by_string)

View File

@ -50,9 +50,10 @@ class TestRegex(yaql.tests.TestCase):
'24.16 = 24(2-4) + 16(5-7)', '24.16 = 24(2-4) + 16(5-7)',
self.eval( self.eval(
r"regex(`(\d+)\.?(\d+)?`).search("r"'aa24.16bb', " r"regex(`(\d+)\.?(\d+)?`).search("r"'aa24.16bb', "
r"format('{0} = {1}({2}-{3}) + {4}({5}-{6})', " r"$.value + ' = ' + "
r"$.value, $2.value, $2.start, $2.end, " r"$2.value + '(' + str($2.start) + '-' + str($2.end) + ') + ' "
r"$3.value, $3.start, $3.end))")) r"+ $3.value + '(' + str($3.start) + '-' + str($3.end) + ')')"
))
def test_search_all(self): def test_search_all(self):
self.assertEqual( self.assertEqual(

View File

@ -118,10 +118,6 @@ class TestStrings(yaql.tests.TestCase):
def test_concat_func(self): def test_concat_func(self):
self.assertEqual('abc', self.eval("concat(a, b, c)")) self.assertEqual('abc', self.eval("concat(a, b, c)"))
def test_format(self):
self.assertEqual('a->b', self.eval("'{0}->{x}'.format(a, x => b)"))
self.assertEqual('a->b', self.eval("format('{0}->{x}', a, x => b)"))
def test_trim(self): def test_trim(self):
self.assertEqual('x', self.eval("' x '.trim()")) self.assertEqual('x', self.eval("' x '.trim()"))
self.assertEqual('x', self.eval("'abxba'.trim(ab)")) self.assertEqual('x', self.eval("'abxba'.trim(ab)"))