jhipster / jhipster/prettier-java

Parse fails on a raw NUL (U+0000) in a string literal since 2.9.0

Chiusa
#1,063 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.