Skip to content

An enabled: false in a server-wide config that is not plain UTF-8 is ignored #40

Open

Description

@dmccoystephenson

An enabled: false in plugins/trace/config.yml is ignored, and reporting stays on, when the file is not plain UTF-8. Two cases were confirmed by running them through build() against a real file.

Where: src/main/java/software/stephenson/trace/TraceClient.java, readServerWideConfig and ENABLED_LINE.

  1. A byte that is not valid UTF-8 anywhere in the file. Files.readAllLines(file, StandardCharsets.UTF_8) throws MalformedInputException, which is an IOException. readServerWideConfig catches it, logs could not read server-wide config at FINE, and returns ServerWideConfig.NONE. The whole file is lost, so a file holding # café saved as ISO-8859-1 above enabled: false leaves the client enabled. Its tags: block is lost as well, and server-id: is not read, so an in-memory ID is used for that process.
  2. A UTF-8 byte order mark on a first-line enabled:. readAllLines keeps the mark as . ENABLED_LINE is ^\s*enabled\s*:\s*(\S+), \s does not match , and String.trim() does not remove it, so the line is not recognised as the switch. A file created by build() starts with a comment, so this needs an operator's own file with enabled: on line 1.

Why it matters: this is the server-wide opt-out, and both cases fail open. Operators edit the file by hand, and some Windows editors save in a legacy code page or add a byte order mark. Without a logger set to FINE, nothing tells the operator that the switch was not honoured. The README's "An IO failure is logged at FINE and counts as enabled" covers case 1 by its letter, but the stated reason for that rule is a read-only plugins directory, not a file that was read and could not be decoded.

Options for the maintainer (this touches the opt-out contract, so it needs a human decision):

  • read the file with a charset that cannot fail (ISO-8859-1 keeps every ASCII enabled: line readable, though non-ASCII tag values would then be decoded wrongly), or decode UTF-8 with replacement rather than failure, and strip a leading ;
  • treat a file that exists but cannot be decoded as opting out. This fails closed, but it adds a new way for the server-wide reason to appear; or
  • keep the behaviour and say in the README "Opting out" table that the file must be UTF-8 without a byte order mark.

Related: #15 and #27, which are other cases of the same switch failing open. A fix for those would not settle this one, because neither case here reaches isOff.

The current behaviour is pinned by the characterization tests serverWideConfig_aByteThatIsNotUtf8LeavesReportingOnYet and serverWideConfig_aByteOrderMarkHidesAFirstLineEnabledFalseYet, added in the Stage B test-expansion PR from the same session.

This issue was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions