jhipster / jhipster/prettier-java
Parse fails on a raw NUL (U+0000) in a string literal since 2.9.0
- Lingua principale
- Java
- Stelle
- 1.2k
- Fork
- 120
- Merge medio
- 1g 11h
- PR unite (30g)
- 31
Descrizione
### Summary
A raw NUL (`U+0000`) inside a string literal is legal Java, but `prettier-plugin-java` 2.9.0 onwards fails to parse a file containing one. 2.8.1 and earlier parse it fine.
This is the same family as #1046 — the web-tree-sitter grammar being stricter than the JLS — but a different rule: that one was identifiers, this is string literal contents, so #1058 does not cover it.
### Reproduction
The literal cannot be pasted into an issue body, so create it with:
```bash
python3 -c "open('A.java','wb').write(b'class A {\n String s = \"foo' + bytes([0]) + b'bar\";\n}\n')"
npx prettier --plugin=prettier-plugin-java --write A.java
```
### Actual
```
[error] A.java: Error: Failed to parse: ... (string_literal (string_fragment) (ERROR (UNEXPECTED ...)))
```
`prettier --write` exits 2 and leaves the file untouched.
### Expected
The file formats, as it does on 2.8.1 and earlier.
### Why this is valid Java
JLS 3.10.5 defines a `StringCharacter` as any `InputCharacter` except `"` and `\`, where `InputCharacter` excludes only CR and LF. `U+0000` is therefore permitted, and `javac` compiles the file without complaint. We have a test file carrying one that has compiled and passed in CI for four months.
### Bisection
Holding `prettier` at 3.4.2 so the plugin is the only variable, against the same real-world file:
| prettier-plugin-java | result |
| --- | --- |
| 2.6.7 | parses OK |
| 2.7.4 | parses OK |
| 2.8.0 | parses OK |
| 2.8.1 | parses OK |
| 2.9.7 | **Failed to parse** |
| 2.10.0 | **Failed to parse** |
| 2.10.3 | **Failed to parse** |
Consistent with the parser switch in 2.9.
### Impact
The failure is a hard stop rather than a formatting difference: prettier cannot format what it cannot parse, so `--write` cannot repair it and `--check` fails the commit. For anyone running prettier from a pre-commit hook, upgrading past 2.8.1 blocks commits on any file containing such a literal, pointing at a byte that is invisible in an editor and in a diff.
The workaround on our side is to write the escape `\0` instead of the raw byte, which is better style regardless — noting that the six-character unicode escape for zero is not a substitute, since Java resolves unicode escapes before lexing and so reintroduces the raw NUL into the token stream.
This is presumably a `tree-sitter-java-orchard` issue rather than prettier-java's own code, but filing here as #1046 was, since this is where the regression surfaces.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Inizia riproducendo il problema con il comando Python fornito e l’invocazione di npx prettier su A.java, quindi confronta il comportamento con 2.8.1. Segui il Parser-Switch introdotto in 2.9 e ispeziona il percorso tree-sitter-java-orchard, insieme alla issue correlata #1046. Il lavoro è completato quando i file contenenti un NUL grezzo in un literal di stringa vengono formattati correttamente e il file di test esistente che ne contiene uno continua a superare i test.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- java
- Ambito
- compilers, tooling
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Attiva
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 48/100