Skip to content

toJSON does not emit canonical JSON for non-finite double/float values, breaking round-trips through JSON.stringify #1260

Description

@jeffw-wherethebitsroam

Using version: 2.11.8

We make use of +-Infinity in our protobuf messages. When using toJSON and JSON.stringify, these values get lost.

syntax = "proto3";
message Msg {
  double min = 1;
}
  const msg = Msg.create({ min: -Infinity })

  const obj = Msg.toJSON(msg)
  // obj => { min: -Infinity }   (raw JS number, not the canonical string)

  const wire = JSON.stringify(obj)
  // wire => '{"min":null}'      (JSON.stringify turns Infinity/NaN into null)

  const back = Msg.fromJSON(JSON.parse(wire))
  // back => { min: 0 }          (value lost)

From the spec it looks like these should be converted to strings and these appear to work with fromJSON if I use a replacer:

function nonFiniteReplacer(_key: string, value: unknown): unknown {
  if (typeof value === 'number' && !Number.isFinite(value)) {
    if (value === Infinity) return 'Infinity'
    if (value === -Infinity) return '-Infinity'
    return 'NaN'
  }
  return value
}

const wire = JSON.stringify(Msg.toJSON(msg), nonFiniteReplacer)
// wire => '{"min":"-Infinity"}'

const back = Msg.fromJSON(JSON.parse(wire))
  // back => { min: -Infinity }

But now I need to track this everywhere! toJSON should convert these to strings to be compatible with cannoncial json.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions