run --goal silently truncates a query at the first unparsed token (wrong-but-successful results) #30

Closed
opened 2026-06-02 20:08:45 +00:00 by navicore · 1 comment
Owner

Summary

prlg run --goal "<query>" parses a single term and silently discards any
trailing tokens. When the query contains an operator the parser doesn't know,
everything from that point on is dropped — and the truncated query can succeed
with a wrong binding.

Repro

$ prlg run --program 'd_(0).' --goal 'X is 8 >> 1, X =:= 4' --format text
X = 8

8 >> 1 is 4, and X =:= 4 should fail for X = 8 — but the query is
truncated at the unknown >> to just X is 8, which succeeds with X = 8.
The trailing conjuncts (>> 1, X =:= 4) are silently dropped.

Another form — trailing garbage is ignored entirely:

$ prlg run --program 'd_(0).' --goal 'member(2,[1,2,3]) zzz' --format text
true.

Contrast: in-file clauses are correct

Clause bodies require a terminating ., so the same construct correctly errors
rather than truncating:

$ printf 't :- X is 8 >> 1, X =:= 4.\n' > /tmp/c.pl
$ prlg run /tmp/c.pl --goal t
Error: Parse error in /tmp/c.pl: expected `.`, got `>` at line 1 col 13

So the bug is specific to the query path (parse_query in
crates/patch-prolog-core/src/parser.rs), which doesn't enforce that the whole
input is consumed.

Impact

A multi-goal --goal query can return a wrong-but-successful result, masking
both unknown-operator errors and real query failures. (loglings itself is not
exposed — it only ever passes the single-atom goals test / true.)

Suggested fix

After parsing the query term(s), require EOF; if tokens remain, raise a parse
error (the same contract the clause reader already enforces with its trailing
.).


Reported against prlg 0.4.1. Found while building the loglings exercises.

## Summary `prlg run --goal "<query>"` parses a **single term** and silently discards any trailing tokens. When the query contains an operator the parser doesn't know, everything from that point on is dropped — and the truncated query can succeed with a wrong binding. ## Repro ``` $ prlg run --program 'd_(0).' --goal 'X is 8 >> 1, X =:= 4' --format text X = 8 ``` `8 >> 1` is `4`, and `X =:= 4` should fail for `X = 8` — but the query is truncated at the unknown `>>` to just `X is 8`, which succeeds with `X = 8`. The trailing conjuncts (`>> 1, X =:= 4`) are silently dropped. Another form — trailing garbage is ignored entirely: ``` $ prlg run --program 'd_(0).' --goal 'member(2,[1,2,3]) zzz' --format text true. ``` ## Contrast: in-file clauses are correct Clause bodies require a terminating `.`, so the same construct correctly errors rather than truncating: ``` $ printf 't :- X is 8 >> 1, X =:= 4.\n' > /tmp/c.pl $ prlg run /tmp/c.pl --goal t Error: Parse error in /tmp/c.pl: expected `.`, got `>` at line 1 col 13 ``` So the bug is specific to the query path (`parse_query` in `crates/patch-prolog-core/src/parser.rs`), which doesn't enforce that the whole input is consumed. ## Impact A multi-goal `--goal` query can return a wrong-but-successful result, masking both unknown-operator errors and real query failures. (loglings itself is not exposed — it only ever passes the single-atom goals `test` / `true`.) ## Suggested fix After parsing the query term(s), require EOF; if tokens remain, raise a parse error (the same contract the clause reader already enforces with its trailing `.`). --- Reported against `prlg` 0.4.1. Found while building the `loglings` exercises.
navicore referenced this issue from a commit 2026-06-02 22:57:26 +00:00
Author
Owner

#34

https://git.navicore.tech/navicore/patch-prolog/pulls/34
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
navicore/patch-prolog#30
No description provided.