Skip to content

Commit

Permalink
Add a safety check about expressions and tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustry committed Nov 6, 2024
1 parent 405b059 commit def9a4d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
16 changes: 16 additions & 0 deletions lizmap_server/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,19 @@ def _server_feature_id_expression(feature_id: str, pk_attributes: list, fields:
expression += QgsExpression.createFieldEqualityExpression(field_name, pk_values[i])

return expression


def qgis_expression(text: str, only_fields: bool = False) -> Tuple[QgsExpression, bool]:
""" Get the QGIS expression. """
exp = QgsExpression(text)
if only_fields:
functions = exp.referencedFunctions()
if len(functions) >= 1:
logger = Logger()
logger.critical(
f"The expression below\n{text}\ncontains some functions : {','.join(functions)}\n"
f"Returning an empty expression."
)
return QgsExpression(''), False

return exp, True
9 changes: 5 additions & 4 deletions lizmap_server/expression_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
get_lizmap_groups,
get_lizmap_user_login,
get_server_fid,
qgis_expression,
write_json_response,
)
from lizmap_server.exception import ExpressionServiceError
Expand Down Expand Up @@ -187,7 +188,7 @@ def evaluate(params: Dict[str, str], response: QgsServerResponse, project: QgsPr
elif isinstance(exp_json, dict):
exp_items = exp_json.items()
for k, e in exp_items:
exp = QgsExpression(e)
exp = qgis_expression(e)[0]
exp.setGeomCalculator(da)
exp.setDistanceUnits(project.distanceUnits())
exp.setAreaUnits(project.areaUnits())
Expand Down Expand Up @@ -716,7 +717,7 @@ def get_feature_with_form_scope(
da.setEllipsoid(project.ellipsoid())

# Get filter expression
exp_f = QgsExpression(exp_filter)
exp_f = qgis_expression(exp_filter)[0]
exp_f.setGeomCalculator(da)
exp_f.setDistanceUnits(project.distanceUnits())
exp_f.setAreaUnits(project.areaUnits())
Expand Down Expand Up @@ -840,7 +841,7 @@ def virtualFields(params: Dict[str, str], response: QgsServerResponse, project:
exp_map = {}
exp_parser_errors = []
for k, e in vir_json.items():
exp = QgsExpression(e)
exp = qgis_expression(e)[0]
exp.setGeomCalculator(da)
exp.setDistanceUnits(project.distanceUnits())
exp.setAreaUnits(project.areaUnits())
Expand Down Expand Up @@ -868,7 +869,7 @@ def virtualFields(params: Dict[str, str], response: QgsServerResponse, project:
# get filter
req_filter = params.get('FILTER', '')
if req_filter:
req_exp = QgsExpression(req_filter)
req_exp = qgis_expression(req_filter)[0]
req_exp.setGeomCalculator(da)
req_exp.setDistanceUnits(project.distanceUnits())
req_exp.setAreaUnits(project.areaUnits())
Expand Down
4 changes: 2 additions & 2 deletions lizmap_server/get_feature_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
)
from qgis.server import QgsServerFilter, QgsServerProjectUtils

from lizmap_server.core import find_vector_layer, server_feature_id_expression
from lizmap_server.core import find_vector_layer, server_feature_id_expression, qgis_expression
from lizmap_server.logger import Logger, exception_handler
from lizmap_server.tools import to_bool
from lizmap_server.tooltip import Tooltip
Expand Down Expand Up @@ -230,7 +230,7 @@ def responseComplete(self):

expression = server_feature_id_expression(result.feature_id, result.layer.dataProvider())
if expression:
expression_request = QgsFeatureRequest(QgsExpression(expression))
expression_request = QgsFeatureRequest(qgis_expression(expression)[0])
if not geometry_result:
expression_request.setFlags(QgsFeatureRequest.NoGeometry)
feature = QgsFeature()
Expand Down
7 changes: 7 additions & 0 deletions test/test_server_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
get_lizmap_config,
get_lizmap_layer_login_filter,
get_lizmap_layers_config,
qgis_expression,
)
from lizmap_server.get_feature_info import GetFeatureInfoFilter
from lizmap_server.tools import to_bool
Expand Down Expand Up @@ -266,3 +267,9 @@ def test_feature_id_expression(self):
"\"field_1\" = '1' AND \"field_2\" = '2'",
_server_feature_id_expression("1@@2", ['field_1', 'field_2'], fields),
)

def test_expression(self):
""" Test about expressions and tokens. """
self.assertTrue(qgis_expression('"hi"')[1])
self.assertTrue(qgis_expression('hi')[1])
self.assertTrue(qgis_expression('lower("hi")')[1])

0 comments on commit def9a4d

Please sign in to comment.