Ignore:
Timestamp:
Jan 28, 2026, 10:24:15 AM (5 hours ago)
Author:
chronos
Message:
  • Fixed: Handling escaped semicolon in indexed property values.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Packages/VCard/VCard.pas

    r173 r199  
    858858function TContactProperty.GetValueItem(Index: Integer): string;
    859859var
    860   List: TStringList;
    861 begin
    862   List := TStringList.Create;
    863   try
    864     List.Delimiter := ';';
    865     List.NameValueSeparator := '=';
    866     List.StrictDelimiter := True;
    867     List.DelimitedText := Value;
    868     if Index < List.Count then
    869       Result := List.Strings[Index]
    870       else Result := '';
    871   finally
    872     List.Free;
    873   end;
     860  I: Integer;
     861  P: Integer;
     862  CurrentIndex: Integer;
     863  CurrentIndexStart: Integer;
     864  CurrentIndexEnd: Integer;
     865begin
     866  CurrentIndex := 0;
     867  CurrentIndexStart := 1;
     868  CurrentIndexEnd := Length(Value);
     869  P := 1;
     870  repeat
     871    I := Pos(';', Value, P);
     872    if I > 0 then begin
     873      if (I > 1) and (Value[I - 1] = '\') then begin
     874        P := I + 1;
     875        Continue;
     876      end else begin
     877        CurrentIndexEnd := I - 1;
     878        if CurrentIndex = Index then begin
     879          Break;
     880        end else begin
     881          P := I + 1;
     882          Inc(CurrentIndex);
     883          CurrentIndexStart := P;
     884          CurrentIndexEnd := Length(Value);
     885        end;
     886      end;
     887    end else begin
     888      Break;
     889    end;
     890  until False;
     891  if Index = CurrentIndex then begin
     892    Result := Copy(Value, CurrentIndexStart, CurrentIndexEnd - CurrentIndexStart + 1);
     893  end else Result := '';
    874894end;
    875895
     
    895915procedure TContactProperty.SetValueItem(Index: Integer; AValue: string);
    896916var
    897   List: TStringList;
    898 begin
    899   List := TStringList.Create;
    900   try
    901     List.Delimiter := ';';
    902     List.NameValueSeparator := '=';
    903     List.StrictDelimiter := True;
    904     List.DelimitedText := Value;
    905 
    906     // Extend subitems count
    907     while List.Count <= Index do
    908       List.Add('');
    909 
    910     List.Strings[Index] := AValue;
    911 
    912     // Remove empty items
    913     while (List.Count > 0) and (List.Strings[List.Count - 1] = '') do
    914       List.Delete(List.Count - 1);
    915 
    916     Value := List.DelimitedText;
    917   finally
    918     List.Free;
     917  I: Integer;
     918  P: Integer;
     919  CurrentIndex: Integer;
     920  CurrentIndexStart: Integer;
     921  CurrentIndexEnd: Integer;
     922begin
     923  CurrentIndex := 0;
     924  CurrentIndexStart := 1;
     925  CurrentIndexEnd := Length(Value);
     926  P := 1;
     927  repeat
     928    I := Pos(';', Value, P);
     929    if I > 0 then begin
     930      if (I > 1) and (Value[I - 1] = '\') then begin
     931        P := I + 1;
     932        Continue;
     933      end else begin
     934        CurrentIndexEnd := I - 1;
     935        if CurrentIndex = Index then begin
     936          Break;
     937        end else begin
     938          P := I + 1;
     939          Inc(CurrentIndex);
     940          CurrentIndexStart := P;
     941          CurrentIndexEnd := Length(Value);
     942        end;
     943      end;
     944    end else begin
     945      Break;
     946    end;
     947  until False;
     948  if Index = CurrentIndex then begin
     949    Value := Copy(Value, 1, CurrentIndexStart - 1) +
     950      AValue + Copy(Value, CurrentIndexEnd + 1, MaxInt);
     951  end else begin
     952    for I := CurrentIndex + 1 to Index do begin
     953      Value := Value + ';';
     954      if I = Index then Value := Value + AValue;
     955    end;
    919956  end;
    920957end;
Note: See TracChangeset for help on using the changeset viewer.