You are not logged in.
Pages: 1
OK, I understand.
Thank you, I will follow your advice.
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.
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.
@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 ?
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.
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.
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.
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;
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 ...
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?
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
@ab Thank you, I understand now !
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;
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
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.
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
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
I tested successfully the last SynTaskDialog and SynPDF patches.
Thank you
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
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
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
Pages: 1