View Issue Details

IDProjectCategoryView StatusLast Update
0006724JEDI VCL00 JVCL Componentspublic2021-09-04 14:14
Reporterkraikov2Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product VersionDaily / GIT 
Target VersionFixed in Version 
Summary0006724: TJvCustomAppIniStorage bad '\n' quotation
DescriptionThe TJvCustomAppIniStorage can store values with newlines, and replaces newlines to '\n'
There is a bug in TJvCustomAppIniStorage.ReplaceCRLFToSlashN, which leads to invalid string will be returned on read in some conditions.
The bug reason is ReplaceCRLFToSlashN does not quote single '\' if no newlines detected in the value.

The TJvCustomAppIniStorage.ReplaceCRLFToSlashN performs newlines replacement only for values with newlines;
but unquotes (calls TJvCustomAppIniStorage.ReplaceSlashNToCRLF) for all values on reading.
So when I write the value 'aaa\nbbb' (value does not contains newlines, the '\n' is the part of the value),
I'll get 'aaa'0000013#10'bbb' on reading.

Here is the bad function from the JvAppIniStorage.pas:

function TJvCustomAppIniStorage.ReplaceCRLFToSlashN(const Value: string): string;
begin
  if (Pos(0000013, Value) > 0) or (Pos(0000010, Value) > 0) then
  begin
    Result := StringReplace(Value, '\', '\\', [rfReplaceAll]); // <- this should be done unconditionally
    Result := StringReplace(Result , 0000013#10, '\n', [rfReplaceAll]);
    Result := StringReplace(Result , 0000010, '\n', [rfReplaceAll]);
    Result := StringReplace(Result , 0000013, '\n', [rfReplaceAll]);
  end
  else
    Result := Value;
end;

Here is the fixed version:
function TJvCustomAppIniStorage.ReplaceCRLFToSlashN(const Value: string): string;
begin
  Result := StringReplace(Value, '\', '\\', [rfReplaceAll]);
  if (Pos(0000013, Result) > 0) or (Pos(0000010, Result) > 0) then
  begin
    Result := StringReplace(Result , 0000010, '\n', [rfReplaceAll]);
    Result := StringReplace(Result , 0000013, '\n', [rfReplaceAll]);
  end;
end;
TagsJvAppIniFileStorage

Activities

kraikov2

2021-08-09 14:58

reporter   ~0021990

Or we can just add '/' char detection in condition:

function TJvCustomAppIniStorage.ReplaceCRLFToSlashN(const Value: string): string;
begin
  if (Pos(0000013, Value) > 0) or (Pos(0000010, Value) > 0) or (Pos('\', Value) > 0) then
  begin
    Result := StringReplace(Value, '\', '\\', [rfReplaceAll]); // <- this should be done unconditionally
    Result := StringReplace(Result , 0000013#10, '\n', [rfReplaceAll]);
    Result := StringReplace(Result , 0000010, '\n', [rfReplaceAll]);
    Result := StringReplace(Result , 0000013, '\n', [rfReplaceAll]);
  end
  else
    Result := Value;
end;

mh

2021-09-04 14:14

reporter   ~0021993

If you know how to create a git pull request then please create one with your proposed changes. Otherwise ask how to do it.

Issue History

Date Modified Username Field Change
2021-08-09 14:25 kraikov2 New Issue
2021-08-09 14:25 kraikov2 Tag Attached: JvAppIniFileStorage
2021-08-09 14:58 kraikov2 Note Added: 0021990
2021-09-04 14:14 mh Note Added: 0021993