Skip to content

f-s must be run binding *read-eval* to false #158

@vemv

Description

@vemv

Problem statement

Some .clj files can contain the reader-eval syntax. https://clojure.org/guides/weird_characters#_reader_eval says:

Note that #= is not an officially supported feature of the reader, so you shouldn’t rely on its presence in future versions of Clojure.

People can include this #= syntax in their .clj files, for reasons (personally I don't recommend so).

When tools.reader, used by our strategies (and potentially used by any of the libs we wrap) encounters a #=(), it will actually trigger Clojure evaluation, while *ns* is bound to a different ns to the one being read.

So if foo.clj contains #=(release-sharks), whenever some other ns attempts to read this file, tools.reader will invoke release-sharks, attempting to resolve it to *ns* (not foo).

This is wrong at several levels:

  • Running code is undesired to begin with
    • Can create very surprising behavior - e.g. running f-s should not cause application-level side-effects
  • because *ns* is bound to a different ns to the one being read, it's very unlikely that function invocations will succeed
    • This causes an exception, making the whole file unreadable.

Proposal

Bind *read-eval* to false in the right place, such that it's always false when running any strategy, linter, formatter, etc.

AC

Ideally, a .clj file containing #=(foo) can be formatted and linted.

Currently, such a file would be excluded at a strategies level:

Alternatives and comparison

  • Bind *ns* to the ns being read
    • This complects code loading/running (a concern of e.g. tools.namespace) with formatting/linting. Generally f-s should not trigger application-level side-effects, perform excessive requires, etc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions