View Issue Details

IDProjectCategoryView StatusLast Update
0035796FPCDatabasepublic2019-07-08 13:10
ReporterZdravko GabrovskiAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.3.1Product Buildtrunk 
Target VersionFixed in Version3.3.1 
Summary0035796: Get string as variant issue in non-utf8 databases
DescriptionInto a simple database application, which will create a LazReport over the non-utf8 firebird database (database character set = NONE, connection character set = WIN1251, new property UseConnectionCharSetIfNone=True), I discover, that LazReport display ????? instead of expected Cyrillic symbols.
After investigation of LazReport source code, I catch that LazReport extract data from the connection with the method
function lrGetFieldValue(F: TField): Variant;
in to lr_dbrel.pas source file, located into component/lazreport/source folder with a get-property call
Result:=F.Value;
located at line 123, where F is a TStringField.
So, this get property F.Value calls a function
function TStringField.GetAsVariant: variant;
located in fields.inc, line 1199.
Originally, function calls GetValue(s) method and assign a value directly to "result " variant, without calling setCodePage method, which will convert resulted variant into a right code page (1251 in my case).
Few lines above into fields.inc I found a method "GetAsString", which have a line "SetCodePage(RawByteString(Result), CP_ACP, True)", which is missing into "GetAsVariant" method.

So, I change the method "GetAsVarinat" to be:


function TStringField.GetAsVariant: variant;

var s : rawbytestring;

begin
  If GetValue(s) then begin
    SetCodePage(s, CP_ACP, True); // <<<<<<<<<<<<<<<<<<<<< Change <<<<
    Result:=s;
  end
  else
    Result:=Null;
end;

and now everything is OK and Lazreport display a report as I expect.

 

Steps To ReproduceDiscovered into description.
Additional InformationPLease, find attached screenshots before and after the fix.
TagsNo tags attached.
Fixed in Revision42344
FPCOldBugId
FPCTarget3.2.0
Attached Files

Activities

Zdravko Gabrovski

2019-07-05 11:22

reporter  

Michael Van Canneyt

2019-07-05 11:46

administrator   ~0117075

I think the CP_ACP should not be hardcoded, but should be the codepage field of TStringField.

Can you test that, please ?

Zdravko Gabrovski

2019-07-05 13:20

reporter   ~0117078

In the beginning I thought exactly the same like you, but after a bit research I found, that they set the right code page inside the function TStringField.GetValue(out AValue: RawByteString): Boolean; into fields.inc.
Last line before method end is SetCodePage(AValue, FCodePage, False); this will set a right code page (1251 in my case), but the last parameter for converting is set to false, because of it function does not convert.
After that they call SetCodePage(RawByteString(Result), CP_ACP, True) which will convert the string.
You can check the "GetAsString" method a few lines above GetAsVariant, I just copy code from there.

BR,Zdravko.

Zdravko Gabrovski

2019-07-05 13:23

reporter   ~0117079

So, I found that the
 CP_ACP = 0; // default to ANSI code page
, for me this means that this will use default code page which is set to 1251 in my case.

LacaK

2019-07-08 08:36

developer   ~0117110

It seems, that dynamic code page of string (although set correctly in TStringField.GetValue) is not honored everywhere (LCL LazReport for instance).
So this is reason why there is string converted to CP_ACP when returning AsAnsiString and so on.
IMO simplest solution would be do for GetAsVariant same as for GetAsString:

function TStringField.GetAsVariant: variant;
var s : rawbytestring;
begin
  If GetValue(s) then
    begin
    SetCodePage(s, CP_ACP, True); // <-- ADDED
    Result:=s;
    end
  else
    Result:=Null;
end;

(this does return for Variant always AnsiString also when UNICODE is active i.e. String=UnicodeString
if needed we can fix this later ;-) )

Zdravko Gabrovski

2019-07-08 12:01

reporter   ~0117112

Yes, I think that this is a solution, please, add it to the trunk if it is possible.

Michael Van Canneyt

2019-07-08 12:27

administrator   ~0117114

Fixed as suggested.

Zdravko Gabrovski

2019-07-08 13:10

reporter   ~0117115

Everything is OK! Great job! Thanks!

Issue History

Date Modified Username Field Change
2019-07-05 11:22 Zdravko Gabrovski New Issue
2019-07-05 11:22 Zdravko Gabrovski File Added: Screenshot at 2019-07-05 12-19-34.png
2019-07-05 11:22 Zdravko Gabrovski File Added: Screenshot at 2019-07-05 12-20-21.png
2019-07-05 11:46 Michael Van Canneyt Assigned To => Michael Van Canneyt
2019-07-05 11:46 Michael Van Canneyt Status new => assigned
2019-07-05 11:46 Michael Van Canneyt Note Added: 0117075
2019-07-05 13:20 Zdravko Gabrovski Note Added: 0117078
2019-07-05 13:23 Zdravko Gabrovski Note Added: 0117079
2019-07-08 08:36 LacaK Note Added: 0117110
2019-07-08 12:01 Zdravko Gabrovski Note Added: 0117112
2019-07-08 12:27 Michael Van Canneyt Status assigned => resolved
2019-07-08 12:27 Michael Van Canneyt Resolution open => fixed
2019-07-08 12:27 Michael Van Canneyt Fixed in Version => 3.3.1
2019-07-08 12:27 Michael Van Canneyt Fixed in Revision => 42344
2019-07-08 12:27 Michael Van Canneyt FPCTarget => 3.2.0
2019-07-08 12:27 Michael Van Canneyt Note Added: 0117114
2019-07-08 13:10 Zdravko Gabrovski Status resolved => closed
2019-07-08 13:10 Zdravko Gabrovski Note Added: 0117115