Recent

Author Topic: Corrupt non-Latin environment-variables in Windows  (Read 2024 times)

Igor Kokarev

  • Sr. Member
  • ****
  • Posts: 370
Corrupt non-Latin environment-variables in Windows
« on: July 14, 2020, 08:32:42 am »
Lazarus 2.0.10 + FPC 3.2.0 (x86-64) returns corrupt non-Latin environment-variables when I use ExpandEnvironmentStringsW() under debugger on Windows 10.

When I run directly the EXE file everything is OK. This problem didn't appear in Lazarus 2.0.6 + FPC 3.0.4 (x86-64).

My app reads a path to App Data and Documents folders. And if my Windows profile name contain Russian symbols ("Игорь") returned path is wrong.

Should I report a bug for Lazarus or FPC?

A test application:

Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. program EnvBug;
  3.  
  4. function ExpandEnvironmentStringsW(lpSrc: PWideChar; lpDst: PWideChar;
  5.   nSize: Cardinal): Cardinal; stdcall; external 'kernel32.dll' name 'ExpandEnvironmentStringsW';
  6.  
  7. function GetEnv(const Name: WideString): WideString;
  8. var
  9.   len  : Cardinal;
  10. begin
  11.   len:=ExpandEnvironmentStringsW( PWideChar(Name), nil, 0);
  12.   if len>0 then begin
  13.     SetLength( Result, len-1 );
  14.     ExpandEnvironmentStringsW( PWideChar(Name), PWideChar(Result), len );
  15.   end else Result:='';
  16. end;
  17.  
  18. procedure Test(const Name : WideString);
  19. begin
  20.   WriteLn( 'EvnVar '+Name,' = ', GetEnv(Name) );
  21. end;
  22.  
  23. begin
  24.   Test('%LOCALAPPDATA%'); WriteLn;
  25.   Write('Press ENTER to Exit'); ReadLn;
  26. end.
  27.  
« Last Edit: July 14, 2020, 09:06:26 am by Igor Kokarev »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Corrupt non-Latin environment-variables in Windows
« Reply #1 on: July 14, 2020, 03:00:45 pm »
Yes please report a bug: Lazarus

EDIT: lets look at my next post first

Also, what happens if you run outside the debugger?

If it is only in the debugger, please go to our sourceforge page
https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2064%20bits/Alternative%20GDB/
And try different versions of gdb.

Or install package LazDebuggerFp, and see if fpdebug does a better job.
« Last Edit: July 14, 2020, 04:09:15 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Corrupt non-Latin environment-variables in Windows
« Reply #2 on: July 14, 2020, 04:03:50 pm »
Are you sure, it is the environment, and not the console to which you write.
Below code prints the ord values for each char, and they seem to be correct.

As I do not have none-latin chars in my path, I went to
menu: Run > Run parameters
and set an env variable
test1=Игорь
test2=äöü

Note the app below also prints the utf8 as ordinals. Windows of course does not return utf8.
It either returns utf16, or the local codepage  (My local codepage has no support for Игорь , hence the äöü)

All instances of Игорь print
1048, 1075, 1086, 1088, 1100,

That is the same under an IDE build with fpc 3.0.4 and 3.2.0

That seems correct according to 1048 = 0x418
https://www.compart.com/en/unicode/U+0418



Code: Pascal  [Select][+][-]
  1. program project1;
  2. {$codepage utf8}
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   windows
  7.   ;
  8.  
  9. {$R *.res}
  10.  
  11. function ExpandEnvironmentStringsW(lpSrc: PWideChar; lpDst: PWideChar;
  12.   nSize: Cardinal): Cardinal; stdcall; external 'kernel32.dll' name 'ExpandEnvironmentStringsW';
  13.  
  14. function GetEnv(const Name: WideString): WideString;
  15. var
  16.   len  : Cardinal;
  17. begin
  18.   len:=ExpandEnvironmentStringsW( PWideChar(Name), nil, 0);
  19.   if len>0 then begin
  20.     SetLength( Result, len-1 );
  21.     ExpandEnvironmentStringsW( PWideChar(Name), PWideChar(Result), len );
  22.   end else Result:='';
  23. end;
  24.  
  25. procedure Test(const Name : WideString);
  26. var
  27.   w: WideChar;
  28. begin
  29.   WriteLn( 'EvnVar '+Name,' = ', GetEnv(Name) );
  30.   for w in GetEnv(Name) do
  31.     write(ord(w), ', ');
  32.   writeln;
  33. end;
  34.  
  35.  
  36.  
  37. const
  38.   t1: widestring = widestring('Игорь');
  39.   t2: UTF8String = 'Игорь';
  40.  
  41.   d1: widestring = widestring('äöü');
  42.   d2: UTF8String = 'äöü';
  43. var
  44.   x: array [0..101] of word;
  45.   y: array [0..101] of byte;
  46.   i: Integer;
  47.   l: DWORD;
  48.   w: WideChar;
  49.   c: Char;
  50. begin
  51.   for w in t1 do
  52.     write(ord(w), ', ');
  53.   writeln;
  54.   for c in t2 do
  55.     write(ord(c), ', ');
  56.   writeln;
  57.   writeln;
  58.  
  59.   l := GetEnvironmentVariableW(pwidechar('test1'), @x[0], 100);
  60.   writeln(l);
  61.   for i := 0 to l-1 do
  62.     write(x[i],', ');
  63.   writeln;
  64.  
  65.   l := GetEnvironmentVariableA(pchar('test1'), @y[0], 100);
  66.   writeln(l);
  67.   for i := 0 to l-1 do
  68.     write(y[i],', ');
  69.   writeln;
  70.   writeln;
  71.  
  72.   writeln;
  73.   writeln;
  74.  
  75.  
  76.   for w in d1 do
  77.     write(ord(w), ', ');
  78.   writeln;
  79.   for c in d2 do
  80.     write(ord(c), ', ');
  81.   writeln;
  82.   writeln;
  83.  
  84.   l := GetEnvironmentVariableW(pwidechar('test2'), @x[0], 100);
  85.   writeln(l);
  86.   for i := 0 to l-1 do
  87.     write(x[i],', ');
  88.   writeln;
  89.  
  90.   l := GetEnvironmentVariableA(pchar('test2'), @y[0], 100);
  91.   writeln(l);
  92.   for i := 0 to l-1 do
  93.     write(y[i],', ');
  94.   writeln;
  95.  
  96.   Test('%test1%'); WriteLn;
  97.   Test('%test2%'); WriteLn;
  98.  
  99.  
  100.   readln;
  101. end.
  102.  

blind

  • Newbie
  • Posts: 1
Re: Corrupt non-Latin environment-variables in Windows
« Reply #3 on: July 14, 2020, 04:31:10 pm »
Are you sure, it is the environment, and not the console to which you write.
Below code prints the ord values for each char, and they seem to be correct.

I created a GUI example on Lazarus that does not use the console.
The program reads all environment variables using the GetEnvironmentStringsW function.
When starting the program without a debugger, the values of the environment variables are correct.
When launched under the debugger on Lazarus 2.0.10, the national symbols are corrupted.

https://drive.google.com/file/d/1ah4lZEY-Nh5qKLD-WN7xL4DmQGlatpyq/view?usp=sharing


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Corrupt non-Latin environment-variables in Windows
« Reply #4 on: July 14, 2020, 04:53:13 pm »
Ok yes, please report.

I can reproduce.

In my first test, I was accidentally using the new fpdebug, and that works.
It does happen under the default gdb based debugger.


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9792
  • Debugger - SynEdit - and more
    • wiki
Re: Corrupt non-Latin environment-variables in Windows
« Reply #5 on: July 14, 2020, 06:16:12 pm »
It appears to be a problem with the updated gdb.

You can download the old one here https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2064%20bits/Alternative%20GDB/GDB%207.3.50/


Igor Kokarev

  • Sr. Member
  • ****
  • Posts: 370
Re: Corrupt non-Latin environment-variables in Windows
« Reply #6 on: July 14, 2020, 06:48:37 pm »
Martin,

Thanks for your reply and alternate solution. I've submited a report for Lazarus:

https://bugs.freepascal.org/view.php?id=37349
« Last Edit: July 14, 2020, 07:20:48 pm by Igor Kokarev »

 

TinyPortal © 2005-2018