JsonObjectParser rejects valid top-level non-object JSON
bug
### Description
`JsonObjectParser` rejects valid JSON input when the top-level structure is not a JSON object. The 256-byte lookup table (`outerChars`) only tolerates `{`, `[`, `]`, `,`, and whitespace at depth 0 outside a string. Any other byte causes a `FramingException` with the misleading message "Invalid JSON encountered".
### Affected code
`stream/src/main/scala/org/apache/pekko/stream/impl/JsonObjectParser.scala` (lines 170-180):
```scala
private val outerChars: Array[Byte] =
Array.tabulate[Byte](256) { i =>
i.toByte match {
case CurlyBraceStart => 2 // found object
case SquareBraceStart | SquareBraceEnd | Comma => 1 // skip
case b if isWhitespace(b.toByte) => 1 // skip
case _ => 0 // error
}
}
```
At depth 0, encountering a byte with value `0` triggers `1 / outer` (line 142), raising `ArithmeticException`, which is converted to a `FramingException`.
### Valid JSON inputs that are incorrectly rejected
| Input | Why rejected |
|-------|-------------|
| `42` (bare number) | `4` → outer=0 |
| `"hello"` (bare string) | `"` → outer=0 |
| `true` / `null` / `false` | `t`/`n`/`f` → outer=0 |
| `[[1], [2]]` (array of arrays) | digits not in skip set |
| `\xEF\xBB\xBF{"a":1}` (UTF-8 BOM) | 0xEF → outer=0 |
### Documentation inconsistency
`JsonFraming.scala` line 56 states "a top-level JSON Array can also be understood" — but this only works for arrays of objects, not arrays of primitives or arrays of arrays.
### Suggested improvements
1. Make the error message more specific: distinguish between "Invalid JSON" and "Top-level JSON element is not a JSON object"
2. Clarify the documentation to state that `JsonFraming.objectScanner` only frames JSON objects
3. Consider supporting UTF-8 BOM at the start of input (strip `\xEF\xBB\xBF` before parsing)
3 条评论