open-formulieren / open-forms

Smart and dynamic forms
https://open-forms.readthedocs.io
Other
35 stars 27 forks source link

Cannot convert string to float during logic check #1831

Closed SilviaAmAm closed 2 years ago

SilviaAmAm commented 2 years ago

Product versie / Product version

1.0.12

Omschrijf het probleem / Describe the bug

Seen in Horst aan de Maas production (from sentry):

During /api/v1/submissions/{submission_uuid}/steps/{step_uuid}/_check_logic

ValueError: could not convert string to float: '280.000,00'
  File "rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "openforms/submissions/api/viewsets.py", line 463, in logic_check
    new_configuration = evaluate_form_logic(
  File "elasticapm/traces.py", line 871, in decorated
    return func(*args, **kwds)
  File "openforms/submissions/form_logic.py", line 84, in evaluate_form_logic
    if jsonLogic(rule.json_logic_trigger, data):
  File "__init__.py", line 245, in jsonLogic
    return operations[operator](*values)
  File "__init__.py", line 164, in <lambda>
    ">": lambda a, b: less(b, a),
  File "__init__.py", line 45, in less
    a, b = float(a), float(b)

Stappen om te reproduceren / Steps to reproduce

No response

Verwacht gedrag / Expected behavior

No response

Screen resolution

No response

Device

No response

OS

No response

Browser

No response

Ewen-Lgy commented 2 years ago

The bug comes from the definition of an advanced logic rule. When you are creating an advanced logic rule, you can compare a field to a string. Now, let's say the field compared is an integer with operatorrs like >, <, ...

json { ">": [ { "var": "number" }, "280.00,00" ] }

This advanced logic rule is considered valid. However, In the JsonLogic verification, as soon as the one of the two compared values is an int or a float, the function will try to convert both values to float type.

image

But the string might not be convertible (like in the above advanced logic rule). In addition, this bug could also be reproduced by switching the values :

json { ">": [ { "var": "text" }, 2800 ] }

In that case, the field is a string but we want to compare it to an int