#1 Re: mORMot 1 » TDocVariant: text encoding » 2022-09-01 13:33:19

MC

OK, I understand.
Thank you, I will follow your advice.

#2 Re: mORMot 1 » TDocVariant: text encoding » 2022-09-01 08:22:27

MC

Thank you for your answers.

@ab
I used the debugger to answer your question.

When I set the property using late-binding with an Ansi string, there is a conversion to RawUTF8.
i.e. vVar1.Objet contains "fenêtre" (AnsiString to RawUTF8 conversion).

When I set the property using late-binding with an RawUTF8, there is also a conversion to RawUTF8 :
i.e. vVar1.Objet contains "{"Objet":"fenêtre"}" (double RawUTF8 conversion).

Whatever the type of the original variable (Ansi or RawUTF8) there is a conversion to UTF8 when setting property via late-binding!

In all cases, VariantSaveJSON give the same value as the variant and the second variant obtained with _Json(vJson) is identical to the first variant.

For me, the problem is that there is always a UTF8 conversion regardless of the original type in the assignment.

I went through the documentation but all the examples I found do not have, unless I am mistaken, characters with a code point greater than 127.

@ttomas

When I use UTF8Encode and UTF8DEcode (from system.pas and intended for WideString, right?), it is exactly the same.

The .pas file is Ansi encoded.

#3 mORMot 1 » TDocVariant: text encoding » 2022-08-31 15:00:18

MC
Replies: 5

Hello.
I am using Delphi 7.
I need to save a file in Json format in one application and load it in a second application.
Originally, the information comes from the GUI and may have a code point greater than 127.
I wanted to use a TDocVariant but I have a problem with the encoding.
First try:

var
  vVar1   : Variant;
  vVar2   : Variant;
  vStr1   : string;
  vStr2   : string;
  vJson : RawUTF8;
begin
  vStr1 := 'fenêtre'; //-> input var with code point greater than 127

  TDocVariant.New(vVar1);
  vVar1.Objet := vStr1;
  vJson:= VariantSaveJSON(vVar1);

  vVar2 := _Json(vJSon); //-> give {"Objet":"fenêtre"}
  vStr2 := vVar2.Objet;

  ShowMessage(vStr2); //-> give "fenêtre" -> not correct
end;

I thought I should use the RawUTF8 type.
Second try:

var
  vVar1 : Variant;
  vVar2 : Variant;
  vStr1 : string;
  vStr2 : string;
  vJson : RawUTF8;
  vUtf1 : RawUTF8;
  vUtf2 : RawUTF8;
begin
  vStr1 := 'fenêtre'; //-> input var with code point greater than 127
  vUtf1 := StringToUTF8(vStr1); //-> input var as RawUTF8

  TDocVariant.New(vVar1);
  vVar1.Objet := vUtf1;
  vJson:= VariantSaveJSON(vVar1);

  vVar2 := _Json(vJson);
  vUtf2 := vVar2.Objet;
  vStr2 := UTF8ToString(vUtf2);

  ShowMessage(vStr2); //-> give "fenêtre"  -> not correct
end;

And now I'm lost!
Thanks a lot.

#4 Re: mORMot 1 » 10.4 sydney issues » 2020-06-08 06:52:30

MC

@ab

At first, I tried to create a VFS and in particular by taking inspiration from https://www.developpez.com/actu/244423/ … ourlourou/.

But I didn't succeed. Too complex for me.

So I used serialize and deserialize which is much simpler and leaves me a complete autonomy on the way to cipher (my ECC AEAD contribution).

After many tests, I was surprised by the performance.

This is in production at my customers.

I have database sizes of 250 MB without any problem.

@utelle

In my program :memory: database is not read only.

I agree with you : in case of a power loss I will loose all changes.

But in memory database could be backuped in interval or when critical tables have been updated ?

#5 Re: mORMot 1 » 10.4 sydney issues » 2020-06-06 16:18:26

MC

Hello

I use

sqlite3.serialize

and

sqlite3.deserialize

in order to encrypt/decrypt SQLite database with ECC to/from disk.

Please see https://synopse.info/forum/viewtopic.ph … 926#p29926.

In pratice I use :memory: database, save it to memory stream and encrypt the stream to disk.

Forloading, I load file to memory stream, decrypt it, and load in memory database with decrypted stream.

I hope it could be useful.

#6 Re: mORMot 1 » Revision 2.x of the framework » 2020-03-04 13:08:29

MC

These proposals seem to me to be heading in the right direction.
All my projects are developed under Delphi 7.
I use third party components that today are not compatible with FPC.

#7 mORMot 1 » ECC File signature [updated] » 2019-09-13 09:50:31

MC
Replies: 1

Hello,

I created a file signature with ECC command line utility following the example in documentation :
https://synopse.info/files/html/Synopse … #TITLE_588

Then I opened the .sign file and modified the first char of md5 and sha256 values.

When I check file signature ECC tell signature is valid.

But I was expecting a result: invalid signature

As documentation says : "Note that you can add whatever JSON field you need to any .sign file, especially in the "meta": nested object, as soon as you don't modify the size/md5/sha256/sign values."

Am I wrong ?

Thank you

--- update ---

The ECCCommandVerifyFile command use TECCSignatureCertified.CreateFromFile which only use the "sign" field of a JSON ".sign" file.

This "sign" field calculation is based on SHA256 of the file.

So other fields in the JSON ".sign" file are present for information only.

#8 mORMot 1 » SQLite3 LoadFromStream and SaveToStream » 2019-07-10 16:19:02

MC
Replies: 0

Hello,

I use these procedures in order to load/save an in memory SQLite3 database from/to an encrypted file with ECC.

Maybe it could be useful for someone...

uses SynSQLite3...

procedure SQLite3_SaveToStream(pcDB : TSQLite3DB; pcStream : TStream);
var
  vSize   : Int64;
  vMemory : Pointer;  
begin

  // Database must be opened before calling

  vMemory := nil;

  try //-> finally

    vMemory := sqlite3.serialize(pcDB, 'main', @vSize, 0);

    if not Assigned(vMemory) then
    begin
      raise Exception.Create('memory allocation error');        
    end;
    
    pcStream.WriteBuffer(vMemory^, vSize);

  finally

    if Assigned(vMemory) then
    begin
      sqlite3.free_(vMemory);
    end;

  end;
end;

procedure SQLite3_LoadFromStream(pcDB : TSQLite3DB; pcStream : TStream);
const
  SQLITE_DESERIALIZE_FREEONCLOSE = 1; // Call sqlite3_free() on close
  SQLITE_DESERIALIZE_RESIZEABLE  = 2; // Resize using sqlite3_realloc64()
  SQLITE_DESERIALIZE_READONLY    = 4; // Database is read-only
var
  vSize       : Int64;
  vMemory     : Pointer;
  vMemoryFree : Boolean;
  vFile       : TFileStream;
begin                                                                         

  // Database must be opened before calling

  vMemory     := nil;
  vMemoryFree := False;

  try //-> finally

    vSize := pcStream.Size;

    if (vSize <= 0) then
    begin
      raise Exception.Create('incorrect stream size');
    end;

    vMemory := sqlite3.malloc(vSize);

    if (vMemory = nil) then
    begin
      raise Exception.Create('memory allocation error'); 
    end;

    vMemoryFree := True;

    pcStream.ReadBuffer(vMemory^, vSize);

    vMemoryFree := False;

    if Integer
    (
      sqlite3.deserialize
      (
        pcDB,
        'main',
        vMemory,
        vSize,
        vSize,
        (SQLITE_DESERIALIZE_FREEONCLOSE or SQLITE_DESERIALIZE_RESIZEABLE),
      )
    ) 
    <> 
    0 
    then
    begin
      raise Exception.Create('deserialize error');     
    end;

  finally

    if (vMemoryFree = True) then
    begin
      if Assigned(vMemory) then
      begin
        sqlite3.free_(vMemory);
      end;
    end;
  end;
end;

#9 Re: mORMot 1 » SynZip.pas missing SynCommons use clause ? » 2019-05-09 15:18:48

MC

Sorry, I meant sure...

Because if PByteArray is an array of 32768 bytes (as declared in SysUtils), I am not supposed to use more than 32768 bytes, no ?

For example, this code worked with a zip of 27,4 Mo :

var
  vContent : RawByteString;
  vZip :TZipRead;
begin
  vContent := StringFromFile('TeamViewerPortable-14.zip');
  vZip := TZipRead.Create(@vContent[1], Length(vContent));
  vZip.UnZipAll('c:\temp\');
  vZip.Free;
end;

I thought Delphi would give me an error.
There is a subtlety that I do not understand ...

#10 Re: mORMot 1 » SynZip.pas missing SynCommons use clause ? » 2019-05-09 13:35:20

MC

Thank you ab for your response.

I tried to open .zip archives from memory with size > 32768 bytes and it did not failed. Unzip was correct.

however, is this secure?

#11 mORMot 1 » SynZip.pas missing SynCommons use clause ? » 2019-05-09 09:37:27

MC
Replies: 5

Hello,

I am using TZipRead under Delphi 7 Pro and open a .zip archive file directly from memory with the constructor

constructor Create(BufZip: PByteArray; Size: cardinal);

.

I was surprised that PByteArray was a reference to SysUtils and not SynCommons ("array[0..32767] of Byte" vs "array[0..MaxInt-1] of Byte").

Is there a reason for this?

Thank you

#12 Re: mORMot 1 » SHA256 of an array » 2019-04-26 07:49:03

MC

@ab Thank you, I understand now !

#13 mORMot 1 » SHA256 of an array » 2019-04-25 12:46:02

MC
Replies: 2

Hello,

I am a little confused about this simple program that calculates the SHA256 of an array of Byte.
The line marked "<=== PB here" does not compile if I write:

vSHA256Static: = SHA256(pointer(vStatic), MAX_T);

The line

vSHA256Static: = SHA256(Pointer(vStatic [0]), MAX_T);

compile but I get an access violation at execution.
The calculation of SHA256 with the dynamic array works perfectly.
I do not understand why.
Thank you for your help

P.S. : I am using Delphi 7 Pro

const
  MAX_T = 22400;
var
  vStatic  : array[0..MAX_T-1] of Byte;
  vDynamic : array of Byte;
  vFS      : TFileStream;
  vSHA256Static : AnsiString;
  vSHA256Dynamic : AnsiString;
begin
  SetLength(vDynamic, MAX_T);
  vFS := TFileStream.Create(---some file greater then MAX_T---, fmOpenRead);
  vFS.Position := 0;
  vFS.ReadBuffer(vStatic[0], MAX_T);
  vFS.Position := 0;
  vFS.ReadBuffer(vDynamic[0], MAX_T);
  FreeAndNil(vFS);
  vSHA256Static := SynCrypto.SHA256(Pointer(vStatic[0]), MAX_T);  // <==== PB here
  vSHA256Dynamic := SynCrypto.SHA256(Pointer(vDynamic), MAX_T);
  ShowMessage
  (
    'Static'#9 + vSHA256Static + #10
  + 'Dynamic'#9 + vSHA256Dynamic
  );
end;

#14 mORMot 1 » Authenticated Encryption with Associated Data sample project » 2019-04-16 08:50:24

MC
Replies: 1

Hello ab,
I really appreciate the ECC command line utility.
But sometimes, I need to achieve symmetric encryption.
So, I propose a sample project of AEAD encryption using mORMot.
I hope you will validate it and add it to the sample projects provided with MORMOT.
Thank you so much.

Source available 30 days :
https://www.swisstransfer.com/d/489a928 … 015b13af5a

Synopse AEAD authenticated-encryption with associated-data
        via AES-256-CFB/PKCS7 over PBKDF2_HMAC_SHA256
----------------------------------------------------------
Using mORMot's SynCrypto rev. 1.18.5029

AEAD help
AEAD crypt -file some.doc -out some.doc.synaead -pass P@ssW0rd -salt salt
       -rounds 60000
AEAD decrypt -file some.doc -out some.doc.synaead -pass P@ssW0rd -salt salt
       -rounds 60000

#15 Re: mORMot 1 » Public-key Asymmetric Cryptography via SynECC for large files » 2019-03-19 13:19:35

MC

The "StringFromFile" and "FileFromString" functions are present in several units needed by the ECC program and the modification is too difficult for me.

This was an opportunity for me to think globally about my project (backup software).

I thought to make the transfer of large files by internet by dividing them into several small pieces to avoid having to transfer everything again in case of error and to parallelize their download in case of restoration.

So, I decided to encrypt these pieces and not the entire file.

With small pieces (<50 MB), ECC works very well and is fast!

Thank you for taking the time to answer me.

Have a good day.

#16 Re: mORMot 1 » Public-key Asymmetric Cryptography via SynECC for large files » 2019-03-19 08:14:08

MC

Hello ab,

I am studying the "SynECC.pas" to see if I could make changes to handle large files.

It's not as simple as I thought !

And it requires a change of TECIESHeader.size from Cardinal to Int64.

How I could change TECIESHeader.size in a way acceptable for you ?

Would you accept 2 new function TECCCertificate.EncryptLargeFile and TECCCertificateSecret.DecryptLargeFile ?

thank you

#17 mORMot 1 » Public-key Asymmetric Cryptography via SynECC for large files » 2019-03-18 10:59:17

MC
Replies: 6

Hello,

I am studying the sample project "mORMot\SQLite3\Samples\33 - ECC" and its documentation.

My goal is to use this library for backup software and it's very well suited for my needs.

But I need to be able to encrypt and decrypt large files (> 4 Gb).

My first tests show that an insufficient memory error is encountered with large files.

Unless I'm mistaken, I think it is due to the use of "StringFromFile" and "FileFromString" functions in "SynECC" and "ECCProcess" units.
These functions read/write a file content into/from a String.

Do I need to modify TECC* objects to handle large files ?

If so, do you have any suggestions or recommendations ?

Could my changes be added to the mormot framework ?

Thank you very much

#18 Re: Source Code repository » Proposed two fix » 2012-10-10 10:29:31

MC

I tested successfully the last SynTaskDialog and SynPDF patches.
Thank you

#19 Re: Source Code repository » Proposed two fix » 2012-10-10 09:09:06

MC

I looked at your patch for SynTaskDialog http://synopse.info/fossil/info/bd704264b5.
Your code is not identical to the one I proposed but seems effectively correct.
So I tried it and... It did not work !
I reused my code and... It did work !
But... I don't know why ???!!!

This the test on a Windows XP where Calibri font is not installed so Tahoma font is used

[...]                  
var
  vDialogue : TTaskDialog;
begin
  vDialogue.Title   := 'My Title';
  vDialogue.Inst    := 'Lorem ipsum dolor sit amet consectetuer';
  vDialogue.Content := 'Libero interdum "' +
                       'necVestibulumidsedetwisinequetinciduntMorbiAliquampedetinciduntSedsempercursusorciipsumipsumegestasProinTortortempus' +
                       '" (' +
                       'neque libero Curabitur Donec non Morbi et odio ' +
                       'Praesent. Felis tincidunt vitae turpis malesuada fames\n\n'+
                       'sodales ac Suspendisse augue Aenean. Euismod Aenean non\n\n' +
                       'Morbi et vitae at hendrerit Quisque vitae accumsan. Tellus pretium adipiscing leo Curabitur\n\n' +
                       'Pellentesque turpis lacus Nulla.\n\n' +
                       'Curabitur faucibus risus eget nisl Lorem libero augue dui Nullam urna. Convallis';
  vDialogue.Buttons := 'Button1'#10'Button2';

  vDialogue.Verify        := 'Ne plus afficher ce message';
  vDialogue.VerifyChecked := False;

  vDialogue.Execute([], 100, [tdfUseCommandLinks], tiWarning);
  [...]

With your code below for AddLabel it does not work

function AddLabel(Text: string; BigFont: boolean): TLabel;
var R: TRect;
begin
  result := TLabel.Create(Form);
  result.Parent := Par;
  result.WordWrap := true;
  if BigFont then begin
    if aEmulateClassicStyle then begin
      result.Font.Height := FontHeight-2;
      result.Font.Style := [fsBold]
    end else begin
      result.Font.Height := FontHeight-4;
      result.Font.Color := $B00000;
    end;
  end else
    result.Font.Height := FontHeight;
  
  Text := CR(Text);
  result.AutoSize := false;
  R.Left := 0;
  R.Top := 0;
  R.Right := aWidth-X-8;
  R.Bottom := result.Height;
  R.Bottom := DrawText(result.Canvas.Handle,pointer(Text),-1,R,DT_CALCRECT or DT_WORDBREAK);
  result.SetBounds(X,Y,R.Right,R.Bottom);
  result.Caption := Text;
  inc(Y,R.Bottom+16);
end;

With my code below it does work

function AddLabel(const Text: string; BigFont: boolean): TLabel;
{NMD}
var
   vRect: TRect;
{NMD}
begin
  result := TLabel.Create(Form);
  result.Parent := Par;
  result.WordWrap := true;
  if BigFont then begin
    if aEmulateClassicStyle then begin
      result.Font.Height := FontHeight-2;
      result.Font.Style := [fsBold]
    end else begin
      result.Font.Height := FontHeight-4;
      result.Font.Color := $B00000;
    end;
  end else
    result.Font.Height := FontHeight;
  result.Left := X;
  result.Top := Y;

  {NMD}
  result.AutoSize := False;
  vRect := Rect(0, 0, aWidth-X-8, result.Height);
  result.Height := DrawText(result.Canvas.Handle, PChar(CR(Text)), - 1, vRect, DT_CALCRECT or DT_WORDBREAK);
  {NMD}

  result.Width := aWidth-X-8;
  result.Caption := CR(Text);
  inc(Y,result.Height+16);
end;

Did
Did I missed enormous something ?
Thanks for your help

#20 Re: Source Code repository » Proposed two fix » 2012-10-08 07:56:24

MC

In the "05 - Report created from code" project from the last mORMot, uncomment the 2 "DrawTitle" calls and run.

[...]
//DrawTitle(edt1.Text,true);
[...]
//DrawTitle('This is your text',false,0,'','bookmarkname');
[...]

The zoom button is not enabled because there is not a least one outline (DrawTitle add an outline when useoutline = true).
Have a nice day

#21 Source Code repository » Proposed two fix » 2012-10-04 12:12:44

MC
Replies: 6

I am a very satisfied user of your tools and congratulate you for your work!

I was faced with two problems I could fix.

SynTaskDialog version 1.17

On one computer the message was larger than the dialog form. Curiously the function AddLabel in TTaskDialog.Execute sets the correct width to the label but after setting the caption the width was larger. I realized that the message had a very very long word (web site adress).

Here are the changes I made:

function AddLabel(const Text: string; BigFont: boolean): TLabel;
var                         // <- NEW
   vRect: TRect;            // <- NEW
begin
  result := TLabel.Create(Form);
  result.Parent := Par;
  result.WordWrap := true;
  if BigFont then begin
    if aEmulateClassicStyle then begin
      result.Font.Height := FontHeight-2;
      result.Font.Style := [fsBold]
    end else begin
      result.Font.Height := FontHeight-4;
      result.Font.Color := $B00000;
    end;
  end else
    result.Font.Height := FontHeight;
  result.Left := X;
  result.Top := Y;

  result.AutoSize := False;  // <- NEW     
  vRect := Rect(0, 0, aWidth-X-8, result.Height); // <- NEW
  result.Height := DrawText(result.Canvas.Handle, PChar(CR(Text)), - 1, vRect, DT_CALCRECT or DT_WORDBREAK); // <- NEW
  

  result.Width := aWidth-X-8;
  result.Caption := CR(Text);
  inc(Y,result.Height+16);
end;

SynPDF 1.16

If I don't have outline in my report, I don't have zoom button enabled !

In the "else" part of the last "if" in the procedure TGDIPages.EndDoc, I replaced "M.Enabled := false;" to "M.Enabled := True;"

procedure TGDIPages.EndDoc;
 [...]
 if UseOutlines and (fOutline.Count>0) then begin
    Root.Enabled := true;
    M := Root;
    for i := 0 to fOutline.Count-1 do
    with TGDIPagereference(fOutline.Objects[i]) do begin
      while (M<>Root) and (cardinal(-2000-M.Tag)<cardinal(fOutline.Count)) and 
         (Rect.Bottom<=TGDIPagereference(fOutline.Objects[-2000-M.Tag]).Rect.Bottom) do
        M := M.Parent;
      M := NewPopupMenuItem(fOutline[i],-2000-i,M);
    end;
  end else
    //M.Enabled := False;  // <- COMMENT
    M.Enabled := True;     // <- NEW
end;

I hope this could help

Board footer

Powered by FluxBB