#1 2018-01-24 18:39:57

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

.InitJSON(...,[dvoJSONObjectParseWithinString]) option wrong Count

Hi @ab,

  I serialize a dynamic RawUTF8 array as JSON, then unserialize the JSON in a TDocVariantData and last element is losed.

  The client application serialize to JSON array:

  ...
  fContactDataQueueDynArray: TDynArray;
  ...
  fContactDataQueueDynArray.Init(TypeInfo(TRawUTF8DynArray), fContactDataQueueArray);
  ... // fill the array
  lData := fContactDataQueueDynArray.SaveToJSON; // lData is RawJSON type and fContactDataQueueDynArray content JSON objects
  ...
  fContactService.RestoreContactFromQueue(aTableId, lData); // invoke the remote service
 ...

  The server application unserialize from JSON array:

  ...
  lContactDataQueue.InitJSON(aQueue, [dvoJSONObjectParseWithinString]); // lContactDataQueue is TDocVariantData type
  ...
  lCount := lContactDataQueue.Count; // HERE "Count" have one less than the elements in the array
  ...

   TDocVariantData.InitJSON with [dvoJSONObjectParseWithinString] option doesn't update correctly the VCount internal property.

   The code with problem is:

function TDocVariantData.InitJSONInPlace(JSON: PUTF8Char;
  aOptions: TDocVariantOptions; aEndOfObject: PUTF8Char): PUTF8Char;
var EndOfObject: AnsiChar;
    Name: PUTF8Char;
    NameLen, n: integer;
    intnames, intvalues: TRawUTF8Interning;
begin
  Init(aOptions);
  ...
    if n>0 then begin
      SetLength(VValue,n);
      repeat
        if VCount>=n then
          exit; // unexpected array size means invalid JSON
        GetJSONToAnyVariant(VValue[VCount],JSON,@EndOfObject,@VOptions,false);
        if JSON=nil then
          exit;
        if intvalues<>nil then
          intvalues.UniqueVariant(VValue[VCount]);
        inc(VCount);
      until EndOfObject=']';
    end else
  ...

my patch:

function TDocVariantData.InitJSONInPlace(JSON: PUTF8Char;
  aOptions: TDocVariantOptions; aEndOfObject: PUTF8Char): PUTF8Char;
var EndOfObject: AnsiChar;
    Name: PUTF8Char;
    NameLen, n: integer;
    intnames, intvalues: TRawUTF8Interning;
begin
  Init(aOptions);
  ...
    if n>0 then begin
      SetLength(VValue,n);
      repeat
        if VCount>=n then
          exit; // unexpected array size means invalid JSON
        GetJSONToAnyVariant(VValue[VCount],JSON,@EndOfObject,@VOptions,false);
        if JSON=nil then begin
          if EndOfObject=']' then // <--- THE PATCH
            inc(VCount);
          exit;
        end;
        if intvalues<>nil then
          intvalues.UniqueVariant(VValue[VCount]);
        inc(VCount);
      until EndOfObject=']';
    end else
  ...

Surely you can correct this the better way.

Thanks.


Esteban

Offline

#2 2018-01-25 00:42:31

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,655
Website

Re: .InitJSON(...,[dvoJSONObjectParseWithinString]) option wrong Count

First of all, I don't understand why you are using dvoJSONObjectParseWithinString option here.
You could just transmit lData as RawJSON (or even variant) to the RestoreContactFromQueue() service, with string escape.
I guess the root problem comes from here.

Your patch is not clear to me as a right solution, since I don't really understand what occurs here.
GetJSONToAnyVariant() returns JSON=nil in case of unexpected end - internally using GetJSONField() - so if it returns nil then there is something unexpected...
Do you have simple code to reproduce the problem?

Offline

#3 2018-01-25 14:57:16

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Re: .InitJSON(...,[dvoJSONObjectParseWithinString]) option wrong Count

Hi @ab, the test case that reproduce the problem is here https://drive.google.com/open?id=1dYnHr … lDFq740vzm

Thanks.


Esteban

Offline

#4 2018-01-26 13:21:53

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Re: .InitJSON(...,[dvoJSONObjectParseWithinString]) option wrong Count

@ab, can you see the problem ?


Esteban

Offline

#5 2018-01-27 16:16:10

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,655
Website

Re: .InitJSON(...,[dvoJSONObjectParseWithinString]) option wrong Count

Now I've seen the issue.

Please check https://synopse.info/fossil/info/7200dbe52a

Thanks for the feedback!

Offline

#6 2018-01-29 14:03:06

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 337

Re: .InitJSON(...,[dvoJSONObjectParseWithinString]) option wrong Count

Works fine.

Thank you.


Esteban

Offline

Board footer

Powered by FluxBB