Issue with TROJSonSerializer ReadArray. It returns a copy of the top-row instead of each row

I created a very simple RODL containing the following two arrays:

  • TROIntegerDynArray = array of integer
  • TROIntegerDynMatrix = array of TROIntegerDynArray

Here is my test that fails:

uses
  System.TypInfo,
  uROJSonMessage;

type
  THackROJSonMessage = class(TROJSonMessage); //to access ReadFromStream

procedure TTestForm.Button1Click(Sender: TObject);
var
  data: TStringStream;
  Msg: THackROJSonMessage;
  lResult: TROIntegerDynMatrix;
begin
  data := nil;
  Msg := nil;
  lResult := nil;
  try
    data := TStringStream.Create('{"version":"1.1","result":[[1,2],[3,4]]}'); //output from an ROServer(!)
    Msg := THackROJSONMessage.Create(nil);
    Msg.ReadFromStream(data);
    Msg.Read('Result', System.TypeInfo(TROIntegerDynMatrix), lResult, []);
    Assert(lResult[0][0] = 1, 'Entry [0, 0] not equal to 1');
    Assert(lResult[0][1] = 2, 'Entry [0, 1] not equal to 2');
    Assert(lResult[1][0] = 3, 'Entry [1, 0] not equal to 3'); //this one fails it returns 1.
    Assert(lResult[1][1] = 4, 'Entry [1, 1] not equal to 4'); //this  one is not reached but would return 2.
    ShowMessage('Test passed succesfully');
  finally
    Msg.Free;
    data.Free;
    lResult.Free;
  end;
end;

Although this bug seems to exist for years, I was too lazy to report it so far. I just checked version 9.3.105.1351 and the bug is still there.

I would suggest to move only one line in uROJSonMessage:

function TROJSONSerializer.ReadArray(const aName: string; aClass: TClass;
  var Ref; ArrayElementId: integer): Boolean;
var
  lItem: TROJSONValue;
  lOld: TROJSONValue;
  lSave: Boolean;
  lOldarrayIndex: integer;
begin
  lOld := fOwner.FCurrObject;
  **//lOldarrayIndex := fArrayIndex; This was in my opinion the wrong place.**
  result := true;
  lItem := IntReadObject(aName);
  if lItem = nil then begin
    TROArray(Ref) := nil;
    exit;
  end;
  **lOldarrayIndex := fArrayIndex; //otherwise,row 0 is returned for each row. And here is the correct version.**
  TROArray(Ref) := TROArrayClass(aClass).Create;
  (...)
end;

If I reported this issue in a wrong format (too much unformatted code?), Iā€™m sorry. But I really hope that this bug is solved in the next version, since with every update I have to catch this one manually.

1 Like

Thanks, logged as bugs://79282

bugs://79282 got closed with status fixed.