Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get parameter with double quotes using ParamStr()

Tags:

delphi

So we have a 3rd party tool that we can't recompile but it uses this ParamStr(Index: Integer) to get command line arguments. I have tried everything I can find on the internet but it will not accept double quote character. I have used escape characters, etc, and created a test app to streamline the testing process and pin down the problem to this function.

Has anyone ever successfully passed double quotes through the command line parameters with this function?

Edit: I've posted my test app below. The processfromcommandline function is from the 3rd party library.

An example input for this would be like this:

"file1.adb file2.adb -p4THISISAPASSWORD"

The password is directly after the -p4. Our password is 'encrypted' and will look something more like this

file1.adb file2.adb -p4$/.;}{3"aG13Sz/"9@;.'

The test app outputs the string it gets using ShowMessage so you can see what delphi is doing.So my input would be something

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, clipbrd;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FParams:      Boolean;
    FAbort:       Boolean;
    FAppPath:     String;
    FLogPath:     String;
    FSuccess:     Boolean;
    FSourceFile:  String;
    FDestFile:    String;
    FParamCount:  Integer;
    FPassword4:   String;
    FKeyFile4:    String;
    FIVFile4:     String;
    FPassword5:   String;
    FKeyFile5:    String;
    FIVFile5:     String;
    procedure ProcessFromCommandLine;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ProcessFromCommandLine;
var bTo4: boolean;
    i,l,sz: Integer;
    s:      String;
    buf:    PAnsiChar;
begin
  bTo4 := False;
  for i := 1 to FParamCount do
   begin
    s := ParamStr(i);
    //s := getCommandLine;
    l := Length(s);
    if (i = 1) then
     FSourceFile := s
    else
    if (i = 2) and (Pos('-',s) = 0) then
     FDestFile := s
    else
    if (l > 3) and ((Pos('-p4',s) > 0) or (Pos('/p4',s) > 0)) then
    begin
      ShowMessage('uh' + s);
      FPassword4 := Copy(s,4,l-3);
      end
    else
    if (l > 3) and ((Pos('-p5',s) > 0) or (Pos('/p5',s) > 0)) then
      FPassword5 := Copy(s,4,l-3)
    else
    if (l > 3) and ((Pos('-i4',s) > 0) or (Pos('/i4',s) > 0)) then
      FIVFile4 := Copy(s,4,l-3)
    else
    if (l > 3) and ((Pos('-i5',s) > 0) or (Pos('/i5',s) > 0)) then
      FIVFile5 := Copy(s,4,l-3)
    else
    if (l > 3) and ((Pos('-k4',s) > 0) or (Pos('/k4',s) > 0)) then
      FKeyFile4 := Copy(s,4,l-3)
    else
    if (l > 3) and ((Pos('-k5',s) > 0) or (Pos('/k5',s) > 0)) then
      FKeyFile5 := Copy(s,4,l-3)
    else
    if (l > 2) and ((Pos('-l',s) > 0) or (Pos('/l',s) > 0)) then
      FLogPath := Copy(s,3,l-2)
    else
    if (s = '-4') then
      bTo4 := True
    else
    if (s = '-5') then
      bTo4 := False;
   end;
   Clipboard.AsText := FPassword4;
   ShowMessage(FPassword4);

end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FParamCount := ParamCount;
  FParams := (FParamCount >= 1);
  if (FParams) then
   ProcessFromCommandLine;
end;

end.
like image 305
D.D Avatar asked Jan 27 '23 09:01

D.D


1 Answers

ParamStr() strips off " quote chars, even in an embedded quoted string, as in your example. Thus

-p4$/.;}{3"aG13Sz/"9@;.'

Gets returned as

-p4$/.;}{3aG13Sz/9@;.'

This is hard coded behavior, you can't change it without altering the RTL's source code.

Even Microsoft does the same thing (see the 2nd and 4th examples), but at least it supports embedded " chars escaped as \". ParamStr() does not support any kind of escaping syntax at all!

In fact, ParamStr() has a few bugs 1 related to its quote handling (such as quoted empty parameters, "", are ignored completely), so I would suggest using the Win32 GetCommandLine() to get the raw command line data and then parse it yourself however you want.

1: bug which were originally logged in the old Quality Central bug tracker, but were never ported to the newer Quality Portal bug tracker, and QC has since been decommissioned and is now offline.

like image 188
Remy Lebeau Avatar answered Feb 11 '23 21:02

Remy Lebeau