適切にフォーマットされていない JSON オブジェクトを非整列化しようとすると、UnMarshall 関数からのオブジェクト参照が期待されますが、nil になります。しかし、アプリケーションを閉じると、そのオブジェクトがメモリ リークを生成します。
TMyObject = class
private
FName: String;
end;
AJSON := TJSONObject.ParseJSONValue('{ type: "MyObject.TMyObject", id: 1, fields: { FName: "David", FAge: 20 } }');
//FAge attribute don't exists in TMyObject, so it raises an exception when unmarshalling
with TJSONUnMarshal.Create() do
begin
try
Result := Unmarshal( AJSON );
//First chance exception at $77322F71. Exception class EConversionError with message 'Internal: Field FAge cannot be found in type TMyObject'. Process MyApp.exe (3056)
finally
Free();
end;
//Here the result is nil, but internally the object was created and is alive
end
function TJSONUnMarshal.Unmarshal(Data: TJSONValue): TObject;
var
Root: TJSONObject;
begin
if not (Data is TJSONObject) then
raise EConversionError.Create(SCannotCreateObject);
// clear previous warnings
ClearWarnings;
Root := TJSONObject(Data);
try
Result := CreateObject(Root)
finally
FObjectHash.Clear;
end;
end;
JSON オブジェクトが予期された形式でない場合、例外が発生しますが、参照を作成したオブジェクトを破棄せず、関数でそれを返しません。
したがって、サーバーを消費する人はいくつかの関数を呼び出すことができ、リクエストに送信された JSON が適切にフォーマットされていることを保証するものは何もありません。
どうすればこのような状況に対処できますか? それぞれのクラスで JSON オブジェクトを検証する方法はありますか?
ps: Delphi XE7 を使用しています。