Wrong implementation of Wide2AnsiMove in paswstring.pas. (Breaks Lazarus and compiled programs on Win9x systems).
Original Reporter info from Mantis: Bart @flyingsheep
-
Reporter name: Bart Broersma
Original Reporter info from Mantis: Bart @flyingsheep
- Reporter name: Bart Broersma
Description:
The implementation of Wide2AnsiMove in ($LazarusDir)/components/lazutils/paswstring.pas uses the wrong count parameter in the call to System.Move().
Therefor assigning a WideString variable to an AnsiString fails.
As a result, in the IDE (on Win9x), the ImageListEditor does no longer function, that is, when you press the Add... button, the OpenPictureDialog does not show.
Somewhere along the line of showing this dialog on Win9x systems there is a call to Wide2AnsiMove with source = LAZ_PIC_DIALOG_TEMPLATE and the resulting outputted AnsiString is LAZ_PIC_DIAL (padded with null-characters or garbage).
Steps to reproduce:
In a Lazarus project include the paswstring unit.
procedure TForm1.TestAllBtnClick(Sender: TObject);
var
W1, W2, W3: WideString;
S1, S2, S3: String;
begin
W1 := 'abc';
W2 := 'ABC';
W3 := WideUppercase(W1);
if W3 <> W2 then writeln('####### Fail on WideUpperCase')
else writeln('WideUppercase OK');
W1 := 'abc';
W2 := 'ABC';
W3 := WideLowerCase(W2);
if W1 <> W3 then writeln('####### Fail on WideLowerCase')
else writeln('WideLowercase OK');
S1 := 'abc';
S2 := 'ABC';
S3 := Utf8UpperCase(S1);
if S3 <> S2 then writeln('####### Fail on Utf8UpperCase')
else writeln('Utf8Uppercase OK');
S1 := 'abc';
S2 := 'ABC';
S3 := Utf8LowerCase(S1);
if S1 <> S3 then writeln('####### Fail on Utf8LowerCase')
else writeln('Utf8Lowercase OK');
W1 := 'ABC';
S1 := W1;
if (S1 <> W1) then writeln('###### Fail on Wide2Ansi')
else writeln('Wide2Ansi OK');
S1 := 'ABC';
W1 := S1;
if (S1 <> W1) then writeln('###### Fail on Ansi2Wide')
else writeln('Ansi2Wide OK');
end;
Build and run on Windows 98 or WindowsME
Expected output:
WideUppercase OK
WideLowercase OK
Utf8Uppercase OK
Utf8Lowercase OK
Wide2Ansi OK
Ansi2Wide OK
Actual output:
WideUppercase OK
WideLowercase OK
Utf8Uppercase OK
Utf8Lowercase OK
###### Fail on Wide2Ansi
Ansi2Wide OK
Additional information:
procedure Wide2AnsiMove(source:pwidechar;var dest:ansistring;len:SizeInt);
var
widestr: widestring;
begin
{$ifdef PASWSTRING_VERBOSE}WriteLn('Wide2AnsiMove START');{$endif}
// Copy the originating string taking into account the specified length
SetLength(widestr, len);
System.Move(source^, widestr[1], len);
This should be replaced by
System.Move(source^, widestr[1], len * SizeOf(WChar));
Patch is attached.
NB. Target = 0.99.0 because this is a regression.