ページ 11

htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 16:56
by blade
ローカルサーバを使ってCGIプログラムを動かしています。

C言語でhtmlを書いていて、前のページで

コード:

<input type=hidden name=string value=Even+if+you+are+not+similar+to+him+,+this+tool+is+taller+than+her>
で次のページへ文字を送り、
getcharで1文字ずつ読み込んで配列に突っ込んだのですが(以下のようにして行い、char配列qへ格納した)

コード:

for ( i = 0; ( ch = getchar() ) != EOF; i++ ) {
        if ( ch == '\r' || ch == '\n' ) {
            i--;
            break;
        } else
            q[i] = ch;
    }
    q[i + 1] = '\0';
qの中身は
string=Even%2Bif%2Byou%2Bare%2Bnot%2Bsimilar%2Bto%2Bhim%2B%2C%2Bthis%2Btool%2Bis%2Btaller%2Bthan%2Bher
となり、qを関数decodeでデコードしたところ 参考(http://vapour.s22.xrea.com/clangdojo/in ... ve_array.c
string=Evenフifフyouフareフnotフsimilarフtoフhimフフフthisフtoolフisフtallerフthanフher
となってしまい、完全にカンマの存在が消えてしまいました。decode()の処理でこうなったようなのですが、どう直せばよいかわかりません。
この関数自体は使いたいため、どうにか少し書き換えて問題を解決したいです。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 17:20
by softya(ソフト屋)
デコード後は、文字コードは16進数ではどうなっていますか?
%x書式などを使って確認してみてください。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 19:14
by blade
softya(ソフト屋) さんが書きました:デコード後は、文字コードは16進数ではどうなっていますか?
%x書式などを使って確認してみてください。
%sで表していたqの中身は%xで表示して、
24ab34となりました。
これで文字コードがわかるのでしょうか。すみません、よく理解していません。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 19:21
by softya(ソフト屋)
char配列qの配列の一要素(char)毎に%x(%02xを推奨)で文字コードを16進数で表示してみてくださいと言うことです。
文字コード(16進数)が分かれば、どのように化けたかが分かります。

C言語でCGIをやる以上は文字コードの仕組みを理解することはデバッグのためにも必須だと思ってください。
「文字コード - Wikipedia」
http://ja.wikipedia.org/wiki/%E6%96%87% ... C%E3%83%89

確かAN HTTPDをお使いだと思いますが、Shift-jisの文字コードがデフォルトなんじゃないかと思います。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 20:04
by blade
softya(ソフト屋) さんが書きました:char配列qの配列の一要素(char)毎に%x(%02xを推奨)で文字コードを16進数で表示してみてくださいと言うことです。
文字コード(16進数)が分かれば、どのように化けたかが分かります。

C言語でCGIをやる以上は文字コードの仕組みを理解することはデバッグのためにも必須だと思ってください。
「文字コード - Wikipedia」
http://ja.wikipedia.org/wiki/%E6%96%87% ... C%E3%83%89

確かAN HTTPDをお使いだと思いますが、Shift-jisの文字コードがデフォルトなんじゃないかと思います。
はい、AN HTTPDを使っております。
文字コードはShift-jisに設定しております。

コード:

73
74
72
69
6e
67
3d
45
76
65
6e
ffffffcc
69
66
ffffffcc
79
6f
75
ffffffcc
61
72
65
ffffffcc
6e
6f
74
ffffffcc
73
69
6d
69
6c
61
72
ffffffcc
74
6f
ffffffcc
68
69
6d
ffffffcc
ffffffcc
ffffffcc
74
68
69
73
ffffffcc
74
6f
6f
6c
ffffffcc
69
73
ffffffcc
74
61
6c
6c
65
72
ffffffcc
74
68
61
6e
ffffffcc
68
65
72
26
6e
6f
6b
6f
72
69
3d
6e
6f
ffffffcc
qの文字ごとになってしまったのですが、%02xで以上のようになりました。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 20:12
by softya(ソフト屋)
string=Even%2Bif%2Byou%2Bare%2Bnot%2Bsimilar%2Bto%2Bhim%2B%2C%2Bthis%2Btool%2Bis%2Btaller%2Bthan%2Bher
の%2B の 部分が 2b にならずに cc になってしまっているようです。
と言うことですので、%2Bを変換している部分をprintfデバッグしてみてください。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 20:54
by blade
softya(ソフト屋) さんが書きました:string=Even%2Bif%2Byou%2Bare%2Bnot%2Bsimilar%2Bto%2Bhim%2B%2C%2Bthis%2Btool%2Bis%2Btaller%2Bthan%2Bher
の%2B の 部分が 2b にならずに cc になってしまっているようです。
と言うことですので、%2Bを変換している部分をprintfデバッグしてみてください。
decode()をした後、上の%2Bは全て"フ"(←文字化け?)になり、カンマの部分の%2Cも同様に"フ"になってしまいました。
フは空白を表しているようです。

%2Bを変換しているのはdecode()の13行目以降の処理です。
inBuf=='%'を条件にして変換しているのが問題なのでしょうか。

コード:

int decode( char *inBuf ) {

    int i;
    int j;
    int n = strlen( inBuf );
    char decodeBuf[3];
    char c[MAXLEN];
    char outBuf[MAXLEN];

    j = 0;

    for ( i = 0; i < n; i++ ) {
        if ( inBuf[i] == '%' ) {
            strncpy( decodeBuf, &inBuf[i + 1], 2 );
            decodeBuf[2] = 0x00;
            sscanf( decodeBuf, "%2x", &c );
            outBuf[ j++ ] = c[MAXLEN];
            i += 2;
        } else
            outBuf[j++] = inBuf[i];
    }
    outBuf[j] = 0x00;
    strcpy( inBuf, outBuf );
    return 0;

}

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 21:00
by softya(ソフト屋)
分からないのでデバッグするんですが、printfデバッグの方法が分かりませんか?

こちらを参考にしてみてください。
「簡単RPG講座 番外編。 デバッグ入門 • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/blog.php?u=114&b=982&c=2

デバッグは自分で考えないと上達しませんので、がんばってみてください。
それと、そんなに難しいコードではないので自力で解析してみてください。
どうしてもわからない部分は補助します。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月21日(月) 23:57
by blade
decodeの中身をいじって特定の文字(今回はカンマ)のときだけは直接カンマを出力するようにしてはみて、今回は正しく動きましたが、
また別の文字が来た場合はとなるとキリがなくなってしまうと思ってしまいました。

コード:

int decode( char *inBuf ) {

    int i;
    int j;
    int n = strlen( inBuf );
    char decodeBuf[3];
    char c[MAXLEN];
    char outBuf[MAXLEN];

    j = 0;

    for ( i = 0; i < n; i++ ) {
        if ( inBuf[i] == '%' ) {
            if(inBuf[i+2]=='C')      //%2C(カンマ)が来たら文字としてのカンマを出力

                outBuf[j++] = ',';

            strncpy( decodeBuf, &inBuf[i + 1], 2 );
            decodeBuf[2] = 0x00;
            sscanf( decodeBuf, "%2x", &c );
            outBuf[ j++ ] = c[MAXLEN];
            i += 2;
        } 
        else
            outBuf[j++] = inBuf[i];
    }
    outBuf[j] = 0x00;

    strcpy( inBuf, outBuf );
    return 0;

}
softya(ソフト屋) さんが書きました:string=Even%2Bif%2Byou%2Bare%2Bnot%2Bsimilar%2Bto%2Bhim%2B%2C%2Bthis%2Btool%2Bis%2Btaller%2Bthan%2Bher
の%2B の 部分が 2b にならずに cc になってしまっているようです。
ccとはなんですか?それと"%2B"が"2b"になってないという意味なのでしょうか。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月22日(火) 00:05
by softya(ソフト屋)
根本的な原因を調べずに誤魔化すのは後々困る事になります。

ccは正確に言うとffffffccです。16進で出した文字コードにありますよね。
あそこは、本来%2bのコードである2bが来るはずです。 文字コードの2bは+なんですよ。
元で+を書いているので復元できていないことになります。
その原因を調べなくてはいけないわけですが、どういうふうにprintfを組み込めば調べられると思いますか?

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月22日(火) 00:53
by blade
softya(ソフト屋) さんが書きました:根本的な原因を調べずに誤魔化すのは後々困る事になります。

ccは正確に言うとffffffccです。16進で出した文字コードにありますよね。
あそこは、本来%2bのコードである2bが来るはずです。 文字コードの2bは+なんですよ。
元で+を書いているので復元できていないことになります。
その原因を調べなくてはいけないわけですが、どういうふうにprintfを組み込めば調べられると思いますか?
今のところ、カンマだけでなく+でさえもフになっているためdecode()のif以下の処理が間違っているということですね。
22行目のsscanfを境に、printfを組むとその後は2Bも2Cも同じ表現に変わってしまいました。

コード:

int decode( char *inBuf ) {

    int i;
    int j;
    int n = strlen( inBuf );
    char decodeBuf[3];
    char c[MAXLEN];
    char outBuf[MAXLEN];

    j = 0;

    for ( i = 0; i < n; i++ ) {
        if ( inBuf[i] == '%' ) {
            /*if(inBuf[i+2]=='C')

                outBuf[j++] = ',';*/
            //if(inBuf[i+2]=='C')continue;

            strncpy( decodeBuf, &inBuf[i + 1], 2 );
            decodeBuf[2] = 0x00;
            printf("decodeBufは%s<br>", decodeBuf);
            sscanf( decodeBuf, "%2x<br>", &c );
            printf("変換後は%2x", decodeBuf);
            printf("cは%2x<br>", c);
            outBuf[ j++ ] = c[MAXLEN];
            i += 2;
        } 
        else
            outBuf[j++] = inBuf[i];
    }
    // printf("outBufは%02xだが<br>", outBuf);
    outBuf[j] = 0x00;

    strcpy( inBuf, outBuf );
    return 0;

}

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月22日(火) 01:07
by softya(ソフト屋)
sscanf( decodeBuf, "%2x<br>", &c );ですが間違いがあります。
scanfの書式を調べなおしてみてください。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月22日(火) 01:47
by blade
softya(ソフト屋) さんが書きました:sscanf( decodeBuf, "%2x<br>", &c );ですが間違いがあります。
scanfの書式を調べなおしてみてください。
http://www9.plala.or.jp/sgwr-t/lib/sscanf.html
sscanf(入力元の文字列,書式を指定した文字列,出力先のアドレスを示す);
これには当てはまっていると思うのですが、どこが誤っているかわかりません。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年1月22日(火) 10:47
by softya(ソフト屋)
こちらの方がわかりやすいと思います。
「scanf関数」
http://www.pc.uec.ac.jp/sp/hshrkw/edu/p ... Ex2-1b.htm

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月14日(木) 18:38
by blade
返事が大変遅くなってすみません。
softya(ソフト屋) さんが書きました:こちらの方がわかりやすいと思います。
「scanf関数」
http://www.pc.uec.ac.jp/sp/hshrkw/edu/p ... Ex2-1b.htm
sscanf( decodeBuf, "%2x<br>", &c );

sscanf( decodeBuf, "%2x<br>", c );
配列名だけでアドレスをあらわしているので,&をはずしました。
そしてその後配列cの中身を空に戻しました。
まだ変換ができていないのですが、あとはどこが誤っているのでしょうか。

コード:

int decode(char *inBuf ) {

    int i;
    int j;
    int n = strlen(inBuf);
    char decodeBuf[3];
    char c[MAXLEN];
    char outBuf[MAXLEN];

    j=0;

    for ( i=0; i<n; i++) {
        if (inBuf[i] == '%' ) {
            strncpy(decodeBuf, &inBuf[i+1], 2);
            decodeBuf[2] = 0x00;
            sscanf(decodeBuf, "%2x", c);
            outBuf[ j++ ] = c[MAXLEN];
            i += 2;
            memset(c, '\0', sizeof(c));
        }
        else
            outBuf[j++] = inBuf[i];
    }
    outBuf[j] = 0x00;
    strcpy(inBuf, outBuf);
    return 0;

}

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月14日(木) 18:42
by softya(ソフト屋)
%xで受取り時の型が違います。
char配列では無いはずですよ。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月14日(木) 21:01
by フィア
え~~~っと、がんばってるところ横槍をさすようで悪いのですが

これじゃだめでしょうか?

第一引数 デコードしたい文字列
第二引数 デコードしたい文字列の文字数

昔、私もC言語でCGIを作ろうとしてたのでその時、使ってました。

コード:

int Dcd(char *set,int a){

	int i,j;
	char buf,*tmp;
	
	if(a==0){
	 return -1;
	}
	
	tmp=(char*)malloc(a);
	for(i=0,j=0;i<a;i++,j++){
	 if(set[i]=='+'){tmp[j]=' ';continue;}
	 if(set[i]!='%'){tmp[j]=set[i];continue;}
	 if(set[++i]>='A'){buf=set[i]-'A'+10;}
	 else{buf=set[i]-'0';}
	
	 buf*=16;
	 if(set[++i]>='A'){buf+=set[i]-'A'+10;}
	 else{buf+=set[i]-'0';}

	 tmp[j]=buf;
	}
	 
	for(i=0;i<j;i++){
	 set[i]=tmp[i];
	}
	set[i]='\0';
	free(tmp);
	
	return 0;
}

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月15日(金) 00:43
by softya(ソフト屋)
フィアさんのソースコードは文字コードが分かっていないと厳しいかもですね。
「JIS X 0201 - Wikipedia」
http://ja.wikipedia.org/wiki/JIS_X_0201
あとmalloc(a);だと終端文字が処理できないです。 あっ、終端文字は処理していないんですね。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月15日(金) 07:06
by フィア
<<フィアさんのソースコードは文字コードが分かっていないと厳しいかもですね。
グハ そういえばそうですね。困りましたね。

<<あとmalloc(a);だと終端文字が処理できないです。 あっ、終端文字は処理していないんですね。
私が使いやすいようにと思って作ったはずですが、あえて終端文字を処理していないようにしたのかは忘れました。

何せ結構昔に作ったものでして、使いやすくはしたはずです。

一見すると指摘どおりmalloc(a+1);

にしておけば問題は起きなさそうですが、この状態でも普通に使えたので気にしませんでした。

気になるなら malloc(a+1); にしてみてくださいね。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月15日(金) 07:14
by フィア
ってさらに一見するとmalloc(a+1);にするとまずい

さすがに自分のソースだと眺めてると大体思い出すって事なのですね

終端文字は最後に処理してるはずだと思います。

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月15日(金) 10:48
by softya(ソフト屋)
そういえば、このフィアさんのコードはバッファオーバーフローの脆弱性(単なるバグと訂正)を持っています。
攻撃されても不正なコードは実行できず落ちるぐらいで済むとは思いますがガードは甘いです。

分かりやすく書きなおしてみました。

コード:

int Dcd( char *srcData, int srcLen ) {

	int iSrc,iDst,iTmp;
	char mojicode, *tmp;
	char *dstData = srcData;

	if( srcLen == 0 ) {
		return -1;
	}

	tmp = ( char* )malloc( srcLen );
	for( iSrc = 0, iTmp = 0; iSrc < srcLen; iSrc++, iTmp++ ) {
		if( srcData[iSrc] == '+' ) {
			tmp[iTmp] = ' ';
			continue;
		}
		if( srcData[iSrc] != '%' ) {
			tmp[iTmp] = srcData[iSrc];
			continue;
		}
		//	文字コードの復元。ここで%で終わっていた場合にバッファオーバーの危険性(読み取り側)
		if( srcData[++iSrc] >= 'A' ) {
			mojicode = srcData[iSrc] - 'A' + 10;
		} else {
			mojicode = srcData[iSrc] - '0';
		}
		mojicode <<= 4;
		if( srcData[++iSrc] >= 'A' ) {
			mojicode += srcData[iSrc] - 'A' + 10;
		} else {
			mojicode += srcData[iSrc] - '0';
		}
		tmp[iTmp] = mojicode;
	}

	//	書き戻す
	for( iDst = 0; iDst < iTmp; iDst++ ) {
		dstData[iDst] = tmp[iDst];
	}
	dstData[iDst] = '\0';
	free( tmp );

	return 0;
}

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月16日(土) 19:57
by へにっくす
blade さんが書きました:まだ変換ができていないのですが、あとはどこが誤っているのでしょうか。
softya さんが書きました:%xで受取り時の型が違います。
char配列では無いはずですよ。
これに追記。
for文でi++やってるのに、
なんで%の解析した後にi += 2;してるの?

Re: htmlで文字を次のページヘ送るときカンマが消えてしまう

Posted: 2013年2月17日(日) 08:21
by フィア
うーんしばらくCGIはやらないので後回しになりそうですが、問題あるのは放置しておけませんね。

いずれまたCGIをするときに改良してみようと思います。
指摘ありがとうございました