在编组的TStringlist上调用TJSONUnMarshal.Unmarshal会导致内存损坏吗?

时间:2016-01-03 14:20:07

标签: delphi delphi-10-seattle

这个问题是提供一个MCVE来说明我之前的答案所揭示的问题:

Unexpected failure of custom registered Reverter using TJSONUnMarshal

在我之前的q中,@ VirusTrinity的答案解决了我最初遇到的问题, 即通过解组操作获得的对象被错误地返回 使用Nil TStringlist字段。但是,修复程序发现了一个新问题,就是这个问题 在关闭应用程序时,它会生成0xC0000005异常,访问冲突 地址0x00000000读取地址0x00000000。下面的代码显示了这种行为,生成 关机时AV相同,原因相同。

由于在Data.DBXJSONReflect中PopulateFields(objFields, Obj, customizer);执行function TJSONUnMarshal.CreateObject(JsonObj: TJSONObject): TObject期间内存损坏,显然会发生AV。

如果您在代码中放置了如下所示的断点,请添加一个监视 TEncoding.FAnsiEncoding然后单步执行

AnObject:= jUnmarshal.Unmarshal(jValue);

你应该发现FMaxCharSize中的值从1变为5(有时候 在之前的q我得到7而不是5)。这种变化似乎是对症 内存损坏,显然导致AV关机。

更新:要查看AV发生的位置,请在类过程TEncoding.FreeEncodings的入口点放置一个断点。对我来说,AV发生在

FreeAndNil(FANSIEncoding);

被调用。

更新#2: TEncoding.FAnsiEncoding损坏的地方是使用Field参数值function TJSONUnMarshal.ClassTypeOf调用FDelimiter并执行语句

    fRtti := tRtti.GetField(Field);

ClassTypeOf的调用来自声明

    else if HasReverter(ComposeKey(ClassTypeOf(Data, FieldName),
    FIELD_ANY)) then

procedure TJSONUnMarshal.PopulateFields

的第30222/3023行

任何人都可以确认问题并告知原因吗?

代码:

program MATest;

{$APPTYPE CONSOLE}

uses Classes, System.SysUtils, JSon, DBXJson, DBXJSONReflect;

procedure Test;
var
  TL1,
  TL2 : TStringlist;
  AnObject : TObject;
  jMarshal: TJSONMarshal;
  jUnMarshal : TJSonUnMarshal;
  jValue: TJSONValue;
begin
  TL1 := TStringlist.Create;
  TL1.Add('AAA');
  try
    jMarshal := TJSONMarshal.Create(TJSONConverter.Create);

    jValue := jMarshal.Marshal(TL1);
    Writeln(jValue.ToString);

    jUnMarshal := TJSONUnMarshal.Create;  //  < Put breakpoint here and
    //  add watch of TEncoding.FAnsiEncoding in System.SysUtils
    AnObject:= jUnMarshal.UnMarshal(jValue);
    TL2 := TStringlist(AnObject);
    Writeln(TL2.Text);
    Readln;

  finally
    jValue.Free;
    jMarshal.Free;
    jUnMarshal.Free;
    TL1.Free;
    TL2.Free;
  end;
end;

begin
  try
    Test;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

0 个答案:

没有答案