CZ-NIC / yangson

GNU Lesser General Public License v3.0
53 stars 20 forks source link

XPath addition empty set index out of range #115

Closed iwanb closed 2 years ago

iwanb commented 2 years ago

This XPath currently fails with IndexError because the nodeset is empty:

    xptest("not(t:contT/t:int8) or t:contT/t:int8 + 2 < 10", "not(test:contT/test:int8) or test:contT/test:int8 + 2.0 < 10.0", True)
tests/test_model.py:474: in xptest
    assert pex.evaluate(node) == res
yangson/xpathast.py:74: in evaluate
    return self._eval(XPathContext(node, node, 1, 1))
yangson/xpathast.py:215: in _eval
    lres, rres = self._eval_ops(xctx)
yangson/xpathast.py:188: in _eval_ops
    return (self.left._eval(xctx), self.right._eval(xctx))
yangson/xpathast.py:274: in _eval
    lres, rres = self._eval_ops(xctx)
yangson/xpathast.py:188: in _eval_ops
    return (self.left._eval(xctx), self.right._eval(xctx))
yangson/xpathast.py:295: in _eval
    lres, rres = self._eval_ops_float(xctx)
yangson/xpathast.py:191: in _eval_ops_float
    return (self.left._eval_float(xctx), self.right._eval_float(xctx))
yangson/xpathast.py:79: in _eval_float
    return float(val)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = []

    def __float__(self: "NodeSet") -> float:
>       return float(self[0].value)
E       IndexError: list index out of range

yangson/nodeset.py:54: IndexError

I expect __float__ should return NaN for an empty set.

Slightly related, the XPath evaluator currently eagerly evaluates both sides of "or" and "and" boolean expressions. It could be lazy/short-circuit like Python instead so the second part of the XPath expression is never evaluated.

I.e. instead of

        lres, rres = self._eval_ops(xctx)
        return lres or rres

do:

        return self.left._eval(xctx) or self.right._eval(xctx)

Same for the AndOperator.

llhotka commented 2 years ago

Fixed in 88b56e622f21fd20b525e06338e92edab270f06e and bd734aba7b4e6b0aa2be142f55593be65d77d9c5, thanks!

iwanb commented 2 years ago

Great, thank you!