@Leledumbo:
Preliminary: I'm speaking here only for the Windows OS.
As long as the strings which contain binary data are only used as a "black box", I guess there are no risks for the binary data to be modified/corrupted.
But, when these strings are used as "strings", I mean when they are used with procedures/functions expecting "real" strings for instance, you can experiment any kind of troubles.
I guess -most of- the RTL functions are probably OK (though I've never made any tests; furthermore the 2.7.x branch is another matter), but it's not the case with LCL ones which expect UTF8 strings by default.
Furthermore, Windows is using internally null terminated strings. If there is null char inside you binary data, and if you pass the corresponding string to a Windows API, your "string" will be truncated to the part being only before the null char.
Sample for a form with an edit control (Edit1) and a button control (Button1):
procedure TForm1.Button1Click(Sender: TObject);
var test: String;
begin
test:='begin'+Chr(0)+'end';
ShowMessage('Before: Len='+IntToStr(Length(test))); // Len=9 (Whole test string)
Edit1.text:=test;
test:=Edit1.text;
ShowMessage('After: Len='+IntToStr(Length(test))); // Len=5 (Only 'begin'),
end;
robert83a1's first sample was potentially facing these 2 problems: i.e. LCL modification, plus Windows API truncation.
Attached a quick (and "dirty") program sample, in order to illustrate what I mean. But any other kind of sample altering string data could do the trick: as mentioned before, storing these strings in a text field inside a database, or in an external text file, and so on...
I've taken exactly your blog sample source code, and modified it for my own purposes (i.e. my modifications are commented with "// Modif", to spot them easily).
This sample does exactly what you've coded: it takes a string, encrypts it and decrypts it (using the BlowFish algorithm and a fixed key). Enter a text into the 'Input' edit box, press 'Test OK', and it should works properly in all cases ('Test OK' could be considered more or less as exactly your own sample).
I've just introduced an optional additional step with 2 possible cases. It's only this part of my code which is interesting for my illustration ('StrEnc' is a string variable which is containing the encrypted string):
case CallOption of
1: // LCL+Windows APIs
begin
Form1.Edit2.Caption:=StrEnc;
StrEnc:=Form1.Edit2.Caption;
end;
2: // Windows APIs only
begin
SendMessageA(Form1.Edit2.Handle, WM_SETTEXT, 0, NativeInt(StrEnc));
i1:=SendMessageA(Form1.Edit2.Handle, WM_GETTEXTLENGTH, 0, 0);
if i1=0 then StrEnc:=''
else begin
Inc(i1);
SetLength(StrEnc, i1);
SetLength(StrEnc, SendMessageA(Form1.Edit2.Handle, WM_GETTEXT, i1, NativeInt(StrEnc)));
end;
end;
// Else, None
end;
-Test OK (CallOption=0): the output encrypted string is stored inside another string (StrEnc), and this other string is used as an input for the decoding step. As mentioned before, it should work properly in any cases (this is what you have tested and mentioned). So, storing these binary data from a string to another one is not a problem by itself. Please note however that the encrypted string displayed into the corresponding edit control (i.e. Edit2) may be incomplete if a null char is present,
-Test KO (CallOption=1): the string receiving the encrypted string is now stored in a edit control, and get back from it (via the LCL). It's supposed to behave as robert83a1's first sample. Here, both the LCL and Windows are interfering, and it should not work in most of the cases (wrong final decrypted string, stream error, ...). Basically, the LCL is first converting the "UTF8 string" into an Ansi or Wide string before passing it to the concerned Windows API, in order to update the text in the edit control. Windows may eventually truncate it, if a null char is present. Finally, the LCL is converting back the edit control text from an Ansi or Wide string to an UTF8 string.
-Test API (CallOption=2): here, the LCL is not involved at all when updating/getting the text in/from the edit control, only the Windows API. So, the only possible change is coming from Windows, which may eventually truncates the string (i.e. if null char present). This one should work as long as there is no such null char inside the encrypted string (you can make a test first, with the 'Test OK' button).
Finally, a few input strings to test some different cases (don't enter the " character):
-"test": OK for 'Test OK', OK for 'Test API' (there is no null char inside the encrypted string), but KO for 'Test KO' (stream error because of the LCL conversions),
-"hello": OK for 'Test OK', KO for 'Test API' (first null char at position 3 in the encrypted string), and KO for 'Test KO' of course,
-"test2": idem as for "hello", except for 'Test API'. The test is still KO (i.e. null char) but there is no stream error; instead, decrypted string <> initial string,
-"r": OK in all cases (no null char and no LCL conversion troubles).
PS. Feel free to discuss and/or contest any part of my posts. I've already offended one person in this topic, and I'd prefer not to offend another one (one per topic is quite enough, I guess).
.