C言語CGI 実行時引数で

[上に] [前に] [次に]
2000/01/10(月) 04:05:30
現在C言語でCGIを作成中なのですが
(HP参照元を取得するCGIを作ってるんです)

------ test.cgi -------

main (int argc,char* argv[])
{
  printf("%s",argv[1]);
}

に test.cgi?文字列 として実行時引数を送った時
送られた文字列が正しく表示されない場合があるんです

具体的には 文字列中に ~ が入ってると \~ をなってしまいます
また = が入ってると なにも表示されなくなってしまいます

実行時引数として送る場合には なにか特別な処理をしなくては
いけないのでしょうか?

B-Cus 2000/01/10(月) 13:23:28
> ~ が入ってると \~ をなってしまいます
> = が入ってると なにも表示されなくなってしまいます
どちらも WWW サーバの仕様です (apache の仕様かもしれない)。

~ の他に ^ $ & などもエスケープされます。
= が入ると argv は空になるので、環境変数 QUERY_STRING を
見なくてはいけません。

いいづか [HomePage] 2000/01/10(月) 13:37:52
B-Cusさんがおっしゃっている「QUERY_STRINGを読む」
関数を作ったことがあるので掲示しておきます。
query_parm(NULL)でパラメタの取得、query_parm("キー")で
その値をかえします。よろしければどうぞ。
(コピーする際は、全角スペースを半角スペースまたはタブに
置き換えてください)。

char  *query_parm( char *key )
{
  static char  *query_key[256], *query_val[256];
  int  content_length;
  char  *envp, *query_string;
  int  ix;

  if ( key == NULL ) {
    /* decide whether method to retrieve parameters */
    envp = getenv ( "REQUEST_METHOD" );
    if ( envp == NULL || *envp == '\0' ) {
      query_key[0] = NULL;
      return ( NULL );
    }
    /* set parameters into query_key[]  */
    if ( !(strncmp ( envp, "GET", 3 ) ) ) {
      envp = getenv( "QUERY_STRING" ) ;
      if ( envp == NULL || *envp == '\0' ) {
        query_key[0] = ( char *) malloc( sizeof (char *) );
        query_key[0] = NULL;
        return ( NULL );
      } else {
        query_string =
            malloc( strlen(getenv("QUERY_STRING")) + 1 );
        strcpy ( query_string, getenv("QUERY_STRING"));
      }
    } else {
      envp = getenv( "CONTENT_LENGTH" );
      content_length = atoi( envp );
      query_string = malloc( content_length + 1 );
      read ( 0, query_string, content_length );
      query_string[content_length] = '\0';
    }
    /* pharse into array  */
    for ( ix = 0; 1 ; ix ++) {
      query_key[ix] = strtok(ix == 0 ? query_string : NULL, "=" );
      if ( query_key[ix] == NULL ) {
        query_val[ix] = NULL;
        break;
      }
      query_val[ix] = strtok(NULL, "&" );
      if ( query_val[ix] == NULL ) {
        break;
      }
    }
    return ( NULL ) ;
  } else {
    for ( ix = 0 ; query_key[ix] != NULL; ix++) {
      if ( strlen( query_key[ix] ) == strlen( key ) ) {
        if ( !strcmp ( query_key[ix], key ) ) {
          return ( query_val[ix] );
        }
      }
    }
    return ( NULL ) ;
  }
}

mm 2000/01/10(月) 22:18:06
質問とぜんぜん関係ないんですが、
>        query_key[0] = ( char *) malloc( sizeof (char *) );
って何か意味があるんでしょうか?

2000/01/11(火) 05:19:58
[[解決]]
 早速の解答ありがとうございます

なるほど そういう事だったんですね
ちなみに WINにanHTTPDいれてやってみたら エスケープされま
せんでした > B-Cusさん

わざわざありがとう ございます
勉強させていただきます(感謝) >いいづかさん

B-Cus 2000/01/11(火) 05:40:32
> WINにanHTTPDいれてやってみたらエスケープされませんでした
| や ; などもエスケープされませんでしたか?

なら、wwwboard か wwwlng あたりを anHTTPD で動かすと、
悪意のあるユーザが任意のプログラムを実行できてしまうかも。
# ほんとにできるかどうかは知らない。

http://www.tohoho-web.com/cgi-bin/wwwlng.txt
...
    &appendMessage($ARGV[1], 1);
...
sub appendMessage #($file, $lockflag){
    local($file, $lockflag) = @_;
    ...
    open(OUT, ">> $file");

2000/01/11(火) 13:46:44
 試してみました。

 ~ ^ ? $ はエスケープされませんでした

& は表示されません | は表示されない上にそれ以降も表示されなく
なります

あ、でも私のanHTTPD 古いから・・・笑 (ver_1.19e)

mm 2000/01/12(水) 03:20:59
AnHTTPd 1.16b でちょっと試してみました。

http://localhost/argument.cgi?aaa|rm+*>test.txt
の場合、perlスクリプトのargument.cgiには、以下の引数が渡ります。
$ARGV[0]=aaa
$ARGV[1]=rm
$ARGV[2]=*>test.txt

http://localhost/argument.exe?aaa|rm+*>test.txt
の場合、引数を表示するDOSコマンドargument.exeの以下の出力内容のtest.txtが作成されます。
arg[0] = C:\ARGUMENT.EXE
arg[1] = aaa
arg[2] = rm
arg[3] = *

パイプでコマンドが実行されることはなさそうですが、
http://localhost/cat.exe?<test.txt
とすると、test.txt が覗けたりするんで、
DOSコマンドを実行するように設定している場合のリダイレクトは
注意が必要でしょうね。

いいづか 2000/01/13(木) 01:24:05
> query_key[0] = ( char *) malloc( sizeof (char *) );
なんだこれは?いらないっすね。

[上に] [前に] [次に]