ahausladen / JsonDataObjects

JSON parser for Delphi 2009 and newer
MIT License
413 stars 160 forks source link

Problem parsing null values #11

Closed kattunga closed 9 years ago

kattunga commented 9 years ago

Hi, when you parse a Json string, null values are stored as jdtObject instead of jdtNone.

Can be reproduced with following code:

procedure TForm2.Button2Click(Sender: TObject);
var
  doc: TJsonObject;
begin
  doc := TJsonObject.Create;
  try
    doc.FromJSON('{"ferrcod": 2, "ferrmsg": null, "ferrval": "pepe"}');
    if doc['ferrmsg'].Typ <> jdtNone then
      raise Exception.Create('Why???');
  finally
    doc.Free;
  end;
end;

This doesn't happen when values are assigned one by one:

procedure TForm2.Button2Click(Sender: TObject);
var
  doc: TJsonObject;
begin
  doc := TJsonObject.Create;
  try
    doc['ferrcod'] := 2;
    doc['ferrmsg'] := null;
    doc['ferrval'] := "pepe";

    if doc['ferrmsg'].Typ = jdtNone then
      raise Exception.Create('Now its ok');
  finally
    doc.Free;
  end;
end;
ahausladen commented 9 years ago

jdtNone tells you that the item doesn't exist. So "Variant-Null" has to become "fdtObject:nil" if it is stored. The bug is that the Variant implementation handles varEmpty and varNull the wrong way.

I'll fix the variant implementation so that it returns "Unassigned" if the item doesn't exist (Typ=jdtNone) and "Null" if it is jdtObject:nil. Setting "Null" changes the value to "jdtObject:nil" and setting "Unassigned" raises an EJsonCastException.

  doc['Key'] := Null;
  Check(doc['Key'].Typ = jdtObject);
  Check(doc['Key'].ObjectValue = nil);

  V := doc['NotSet'];
  Check(O['NotSet'].Typ = jdtNone);
  Check(VarIsEmpty(V));
kattunga commented 9 years ago

Sorry, I was not correctly understanding the meaning of jdtNone.

ahausladen commented 9 years ago

You found a bug anyhow.