Skip to content

JsonObjectParser rejects valid top-level non-object JSON #3244

Description

@He-Pin

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):

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    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