IndySockets / Indy

Indy - Internet Direct
https://www.indyproject.org
434 stars 147 forks source link

IdSSLOpenSSL - UTC_Time_Decode - convert to char should be PAnsiChar instead of PChar on Unicode - Solved #531

Closed xjikka closed 2 months ago

xjikka commented 2 months ago

TIdX509.RnotBefore raising EConvertError with message 'Invalid argument to date encode'.

Unit: IdSSLOpenSSL Function: UTC_Time_Decode

Changed lines: ... //Result := 1; //XJIKKA 20240410 result 1 (on error) will raise EConvertError in UTCTime2DateTime with message 'Invalid argument to date encode'. Result := 0; //XJIKKA 20240410 default changed to 0 because of exits ... //SetString(LTemp, PChar(UCTtime^.data), UCTtime^.length); //using PChar I'm getting '??????Z?????'#0 (Delphi 11.3) SetString(LTemp, PAnsiChar(UCTtime^.data), UCTtime^.length); //using PAnsiChar everything OK ('190807084534Z') ... Result := 1; //everything ok, set 1; ...

whole function including changes:

  function UTC_Time_Decode(UCTtime : PASN1_UTCTIME; var year, month, day, hour, min, sec: Word;
    var tz_hour, tz_min: Integer): Integer;
  var
    i, tz_dir: Integer;
    time_str: string;
    {$IFNDEF USE_MARSHALLED_PTRS}
      {$IFNDEF STRING_IS_ANSI}
    LTemp: AnsiString;
      {$ENDIF}
    {$ENDIF}
  begin
    //Result := 1;  //XJIKKA 20240410 result 1 (on error) will raise EConvertError in UTCTime2DateTime with message 'Invalid argument to date encode'.
    Result := 0;  //XJIKKA 20240410 default changed to 0 because of exits
    if UCTtime^.length < 12 then begin
      Exit;
    end;
    {$IFDEF USE_MARSHALLED_PTRS}
    time_str := TMarshal.ReadStringAsAnsi(TPtrWrapper.Create(UCTtime^.data), UCTtime^.length);
    {$ELSE}
      {$IFDEF STRING_IS_ANSI}
    SetString(time_str, PAnsiChar(UCTtime^.data), UCTtime^.length);
      {$ELSE}
    //SetString(LTemp, PChar(UCTtime^.data), UCTtime^.length);    //XJIKKA 20240411 - using PChar I'm getting '??????Z?????'#0 (Delphi 11.3)
    SetString(LTemp, PAnsiChar(UCTtime^.data), UCTtime^.length);  //XJIKKA 20240411 - using PAnsiChar everything OK ('190807084534Z')
    // TODO: do we need to use SetCodePage() here?
    time_str := String(LTemp); // explicit convert to Unicode
      {$ENDIF}
    {$ENDIF}
    // Check if first 12 chars are numbers
    if not IsNumeric(time_str, 12) then begin{$MESSAGE WARN '11.04.2024 14:54:52 - test'}
      Exit;
    end;
    // Convert time from string to number
    year := IndyStrToInt(Copy(time_str, 1, 2)) + 1900;
    month := IndyStrToInt(Copy(time_str, 3, 2));
    day := IndyStrToInt(Copy(time_str, 5, 2));
    hour := IndyStrToInt(Copy(time_str, 7, 2));
    min := IndyStrToInt(Copy(time_str, 9, 2));
    sec := IndyStrToInt(Copy(time_str, 11, 2));
    // Fix year. This function is Y2k but isn't compatible with Y2k5 :-(    {Do not Localize}
    if year < 1950 then begin
      Inc(year, 100);
    end;
    // Check TZ
    tz_hour := 0;
    tz_min := 0;
    if CharIsInSet(time_str, 13, '-+') then begin    {Do not Localize}
      tz_dir := iif(CharEquals(time_str, 13, '-'), -1, 1);    {Do not Localize}
      for i := 14 to 18 do begin  // Check if numbers are numbers
        if i = 16 then begin
          Continue;
        end;
        if not IsNumeric(time_str[i]) then begin
          Exit;
        end;
      end;
      tz_hour := IndyStrToInt(Copy(time_str, 14, 15)) * tz_dir;
      tz_min  := IndyStrToInt(Copy(time_str, 17, 18)) * tz_dir;
    end;
    Result := 1; //XJIKKA 20240410 everything ok, set 1;
  end;

IdSSLOpenSSL.zip

xjikka commented 2 months ago

Sorry, it doesn't belong here, it's about Indy with OpenSSL 3 - (Indy.proposedUpdate).