#1 2021-03-25 05:57:23

Chaa
Member
Registered: 2011-03-26
Posts: 244

Access violation on published TSQLRecord properties

When I use TSQLRecord published properties, as documented in 5.1.7. TSQLRecord fields, there is access violation in TJSONSerializer.WriteObject when handling woDontStore0 option. And woDontStore0 in DEFAULT_WRITEOPTIONS so I can not avoid it.
Minimal code:

type
  TSQLFolder = class (TSQLRecord)
  end;
  TSQLFile = class (TSQLRecord)
      FFolder: TSQLFolder;
  published
      property Folder: TSQLFolder read FFolder write FFolder;
  end;
var
  f: TSQLFile;
begin
  f := TSQLFile.Create;
  f.Folder := TSQLFolder(10);
  ObjectToJSON(f, [woDontStore0]);
end;

Exception EAccessViolation raised with message "Read of address 0000000A".
The problem is in TJSONSerializer.WriteObject for Kind = tkClass.
Function IsObjectDefaultOrVoid called before PropIsIDTypeCastedField, and it is treated Obj as TObject, not as an ID.

Offline

#2 2021-03-25 09:28:39

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

Re: Access violation on published TSQLRecord properties

It is as designed.
TSQLFolder(10) is a trick at ORM level only, not for normal serialization.

Offline

#3 2021-03-26 03:32:36

Chaa
Member
Registered: 2011-03-26
Posts: 244

Re: Access violation on published TSQLRecord properties

That's worked fine until commit https://github.com/synopse/mORMot/commi … 6b9bf508ba because there is function PropIsIDTypeCastedField that can distinguish TObject and ID fields.

So, if it is designed, how can I call interface-based services with TSQLRecord as parameters?

Offline

#4 2021-03-26 05:52:41

Chaa
Member
Registered: 2011-03-26
Posts: 244

Re: Access violation on published TSQLRecord properties

I propose this changes:

--- a/mORMot.pas
+++ b/mORMot.pas
@@ -51009,11 +51009,11 @@ var Added: boolean;
       tkClass: begin
         Obj := P^.GetObjProp(Value);
-        if not(woDontStore0 in Options) or not IsObjectDefaultOrVoid(Obj) then
           if PropIsIDTypeCastedField(P,IsObj,Value) then begin
             HR(P);
             Add(PtrInt(Obj)); // not true instances, but ID
-          end else if Obj<>nil then begin
+          end else if (Obj<>nil) and
+            (not(woDontStore0 in Options) or not IsObjectDefaultOrVoid(Obj)) then begin
             HR(P); // TPersistent or any class defined with $M+
             WriteObject(Obj,Options);
           end;

Last edited by Chaa (2021-03-26 05:53:21)

Offline

#5 2021-03-26 08:15:01

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

Re: Access violation on published TSQLRecord properties

TSQLRecord with joins are not meant to be serialized - at least, I never serialized them in inteface-based services. wink
I don't like this JOIN feature. It was an awful trick from 10 years ago, and I am really tempted to get rid of it for mORMot 2.

But you are right about the need to a fix.
Please check https://synopse.info/fossil/info/1d91ac0dcd

Offline

#6 2021-03-26 09:01:09

Chaa
Member
Registered: 2011-03-26
Posts: 244

Re: Access violation on published TSQLRecord properties

OK, thank's!
Yes, It's really old code, from about 2012.

Last edited by Chaa (2021-03-26 09:01:30)

Offline

Board footer

Powered by FluxBB