• ベストアンサー

制御コード文字の受け取りと処理

普通に作ると、制御コード文字の入力時に不具合を起こすので、何らかの処理をしなくてはなりません。 <>\"';,?&などです。 <>などは、&lt;や&gt;に変換してしまえば良いの、ですが他の文字は入力を許し、データファイルにも書き残したいのです。 気をつけることは、 (1)データファイルのフィールド・デリミッタを、タブなどのこれらに無いものにすること。 それから、何をしたら良いでしょう? 特に、?や&は起動時のパラメータ渡しに使いますので、それを入力されると困りますね。 \'";も同じですが、どのような処理をすれば良いのかアドバイスいただけるとありがたいです。 ちなみに、私は中級レベルと考えていただいて良いかと思います。 つまり、ゼロから作る力は無くても、フリーのCGIなどを自分の仕様に合うようにグチャグチャに改造する力はあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

フォームの送信では、次のようなことが行われます。 ・A タグの href やフォームのvalue値(HTMLに書かれているもの)に含まれる「文字参照」が実文字に置換される。 ・半角の英数字とアンダースコア以外の文字がURLエンコードされる。 ※まれにアンダースコアもURLエンコードするブラウザあり。 受信したデータは、まずフォーム入力時の状態に復元する必要があります。 これがよく「デコード」と言われている処理になります。 ・パラメータの取得、分解、及び変数への格納 ・URLデコード ・漢字コードの変換など(必要に応じて) ※作るCGIの内容により、それ以外の加工を施すこともあります。 これら「送信時の変換」と「デコード」によって、質問にあるパラメータ渡しの文字云々は心配ないわけです。 その後のデータの扱いは「手を加えず持ち回し、必要な所ではコピーを作って加工する」が基本です。 プログラムで行う処理を書き出し、それぞれの仕様に適した変換関数を作成しましょう。 その際、「ある変換関数の結果を更に変換する関数」というのを作らないことが、後の間違いを減らすことになります。 以下にいくつかの用途と必要な処理、注意事項を記しました。 参考になれば幸いです。 □外部記憶への保存、復帰 ・データが保存形式にとって問題となる文字を含む可能性がある場合、変換、復元処理を通す。  (例えば、行/レコード形式で保存する場合、TEXTAREAで入力した改行は変換しなければなりません。   Spurさんのファイル出力形式が不明なので、これ以上のアドバイスは難しいです。) □HTMLへの出力 ・< > & を文字参照に置換する。 ※掲示板など、入力データを表示するのがメインのCGIでは、デコード時にこの処理を行うこともよくあります。 ○タグの属性値として出力する際の注意 ・属性値をダブルクォートで囲む場合、属性値内のダブルクォートは文字参照(&quot;)にする。  (通常のテキストとして出力する場合でも、ダブルクォートを文字参照化して問題ありません。) ○パラメータ付きCGIへのリンク(URL)を出力する際の注意 ・パラメータのキーと値は、URLエンコードしたものを使う。  (キーはエンコードする必要のない文字列にしておくと、処理が減ってラクできます。) ・URLを組み立てる際、「キー=値」を連結する & にも文字参照の &amp; を使う。 □正規表現としての利用 ・データ内に正規表現のメタ文字があると正しく実行されないので、quotemeta関数を通した文字列を使う。   my $tmp = quotemeta($var);   $str =~ /$tmp/;

Spur
質問者

お礼

非常に丁重な解説をいただき、ありがとうございました。 「なるほど~」と頷きながら読ませていただきました。 先日、フォームメールcgiを作って、アドレス欄も入力するようにして、そこに「;」や「,」で複数のアドレスを入れたらうまくいかなかったり、掲示板cgiで、「\」を入力したら異常な動作をしたのです。 それで、それらは普通では入力できないのだと考えていました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • duckling
  • ベストアンサー率47% (88/185)
回答No.2

> 例えば、入力に「\1,000」を入れた場合は、CGIに引き渡される形として、 > http://www.xxx.yyy.jp/cgi-bin/xxx.cgi?\1,000 > となるわけで、その場合に困らないかと考えていました。 「\1,000」は「%5C1%2C000」 「?&\'";」は「%3F%26%5C%27%22%3B」という形に URLエンコードされて送られるので問題ありません。 デコードされたデータをあえて 自分でハイパーリンクのURLなどに入れてしまう場合はまた別です。 私が「改造だけでは中級レベルとは言えない」と思う理由は 「どのような構成でプログラムを作るか」 「その際にどのような不具合が発生するか」「不具合にどう対処するか」 それを考える必要があるからです。 「中級」 = 「普通」と考えるべきだと思うので 「CGI改造の上級」でも、「プログラミングの中級」とは言えないと思います。 データがURLエンコードされて送られる、 ということを知らない故にこの質問をしたと思うので。

Spur
質問者

お礼

わかりました。ありがとうございました。 ★「中級」うんぬんの問題 私は30年ほど前にAssemblerは勉強していたのですが、perlは基本などの勉強をせず、見よう見真似というか、実践でというか、そういう覚え方をしてきたものですから、知らないことも多いと思います。 でも、プログラミングはできますよ。perlはそれほど難しくないですからね。 しかし、これは今回の質問とは論点が違いますので・・・

全文を見る
すると、全ての回答が全文表示されます。
  • duckling
  • ベストアンサー率47% (88/185)
回答No.1

?&\'"; は プログラムに送信される場合はURLエンコードされるので パラメータ渡しに使う文字云々を心配する必要はありません。 しかし送られたデータをそのままURLなどに格納する場合は、 エスケープしましょう。 > ゼロから作る力は無くても ゼロから作る力がないのは中級レベルとは言えないと思います。

Spur
質問者

お礼

回答ありがとうございます。 そうですか、「?&\'"; 」はそのままで受け取れますか? 以前それで失敗していたのでできないものと考えていました。 例えば、入力に「\1,000」を入れた場合は、CGIに引き渡される形として、 http://www.xxx.yyy.jp/cgi-bin/xxx.cgi?\1,000 となるわけで、その場合に困らないかと考えていました。 「ゼロから作る力がないのは中級レベルではない」ですか?(苦笑) 「グチャグチャに」改造する、と表現したのですが・・・ つまり、ほとんどゼロからの作り直しに近い改造もやっています。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 「制御コード」について

    「制御コード」のイメージがうまく沸きません。今は、文字コードごとにつけられた表示する時に使われるコード、くらいのイメージです(例えば、エディタで改行するときは、改行のためのコードが割り当てられていて、それが一つの制御コード、のような感じ)。 この制御コードは、文字コードごとに違うのでしょうか?とすると、違った文字コードで読み込んだ場合、改行などの処理が間違って表示されるのでしょうか? よろしくお願いします。

  • 文字実体参照が勝手に変換されてしまう

    簡単な問合せフォームを作成中に文字実体参照に変換した文字が、元に戻されてしまい困っています。簡単なサンプルを作成してみましたが、以下の様な状態です。 1.入力フォームを持ったHTMLに 「<>と&lt;と&gt;」 と入力し、xxx.cgiに渡します。 2.xxx.cgi内で入力文字列を取得し、文字実体参照に変換後<hidden>で値を保持、再度xxx.cgiに<hidden>の文字列を渡すようにします。この時点で入力値は 「&lt;&gt;と&amp;lt;と&amp;gt;」 となります。 3.再度xxx.cgiが呼ばれると、文字実体参照に変換する処理が行われる為、入力値が 「&amp;lt;&amp;gt;と&amp;amp;lt;と&amp;amp;gt;」 となるはずですが、 「&lt;&gt;と&amp;lt;と&amp;gt;」 となってしまいます(変換処理が行われているはずなのに変換されていない)不思議に思って変換前のCGIの引数を確認してみると、 「<>と&lt;と&gt;」 と文字実体参照が元に戻されてしまっています。 ちなみに文字実体参照の変換処理は$valueに対象の文字が入っているとして以下の方法で変換しています。 ---------- $value =~ s/&/&amp;/g; $value =~ s/"/&quot;/g; $value =~ s/</&lt;/g; $value =~ s/>/&gt;/g; $value =~ s/\n/<BR>/g; ---------- こういった現象についてでも何か分かるようでしたら宜しくお願いします。

    • ベストアンサー
    • Perl
  • テキストファイルのデータ区切り文字(制御文字)について

    テキストファイルにデータを保存しているのですが、区切り文字タブ\tはフィールドの区切りに使っています。 その状態で、仮に1つのフィールドにデータを詰め込む場合、,(カンマ)で区切った場合にデータ自体に金額の,があった場合、誤動作します。フィールドの区切りはタブ\tは普通ですが、1つのフィールドに複数データを持たせる場合の区切り文字は\0など使っても問題ないのでしょうか? 環境はWindows, Linux両方で使います。\0を使ってそれが文字列の最後とまた誤動作しても嫌です。 皆さんは\t以外にテキストデータの区切りにどのような制御文字を使っていますか?ちなみに改行は1レコードの区切り文字です。

    • ベストアンサー
    • Perl
  • 制御文字を含む文字列を扱うには

    field char(50) binary not null unique primary key,fulltext (field) この設定で作られたフィールドがあり、主にlike検索をされます。 このフィールドには本来10進数の数字の文字列を入力する事を考えていたのですが、(数値としては桁数が大きすぎる事と、その数字列の中に"123"を持つ物を探すなど数量とは関係無い検索がされる事から文字列にしています) MySQLのリファレンスによると、インデックスの対象になる文字列は桁数が短い方がいいようなので、どうせ数値でなく文字列を使っているのならと思い、1バイトで表現出来る全ての文字を使い256進数で表し、桁数を節約しようと考えました。 256進数に直してしまうと10進数の状態で"ある数字列"を持つのかどうか分からなくなるのではないかと思うかもしれませんが、それはこのフィールドに行われるlike検索の特徴により解消されます。 長い前置きでしたが、質問はタイトル通り制御文字を含む文字列を扱う事、言い換えれば0~255の全ての文字コードを文字列データとしてMySQLでインサート・全文インデックス・セレクトする方法です。このフィールドのデータは出力される事は無く、selectのwhere部分に使われ、出力されるのは同レコード内の別のフィールドのデータです。 素直に以下のコードでテストしましたが失敗しました。 while ($i < 50){ $rand = mt_rand(0,255); $str .= chr($rand); $i++; }/*insertする文字列$strを生成*/ $sql = "insert into table(field) values ('$str')" $strの中に制御文字や"や'等の文字が入るとinsertが失敗し、追加出来たレコードについても、コマンドプロンプトからselectして出力してみるとPCが警告音を連発します。 何か方法は無いでしょうか?

    • ベストアンサー
    • MySQL
  • HTMLで入力値を半角大文字に制御

    こんにちわ。 HTMLで入力される場合、必ず半角大文字に制御したいのですが、 スタイルシートはIMEのオン・オフしか制御できず、大文字に 固定制御することができません。 JavaScriptでonChange時にでも入力値を大文字に変換という手も あると思うのですが、出来たらそんな面倒なことをせずとも 制御したいと思っています。 もし良い方法がありましたら、是非、教えて下さい。 どうぞ宜しくお願い致します。

    • ベストアンサー
    • HTML
  • 正規表現:対応する文字列A~文字列Bの検索(入れ子あり)

    いつもお世話になります。 以下のように (??{}) というのを使うと正規表現を再帰することによって入れ子があっても対応するカッコにマッチできることが分かりました。 以下のプログラムでは < から対応する > までを抜いています。 #! perl # betweenBracket -- < から対応 > までを抜く # 全角ブランクで字下げを表現しています。 $re = qr/  <   [^<>]*   (?:    (??{$re})    [^<>]*   )*  > /x; while(<DATA>) {  chomp;  for (/$re/g) {   print "$_ ";  }  print "\n"; } __DATA__ I <love> you I <love> <you> <I <love> <you>> 実行結果: <love> <love> <you> <I <love> <you>> これですが、<、>のような1文字のカッコではなくて文字列による開始~終了でもできるでしょうか。 具体的に言うと &lt; から &gt; までと言う風にしたいです。 #! perl # betweenEntity -- &lt; から対応 &gt; までを抜く ・・・???・・・・ __DATA__ I &lt;love&gt; you I &lt;love&gt; &lt;you&gt; &lt;I &lt;love&gt; &lt;you&gt;&gt; 実行結果: &lt;love&gt; &lt;love&gt; &lt;you&gt; &lt;I &lt;love&gt; &lt;you&gt;&gt; よろしくお願いします!

    • ベストアンサー
    • Perl
  • jsp 改行コードで改行させて表示したい

    はじめまして。 PostgreSQLから読み込んだ文字列データを表示させるtomcat+struts+servlet/jspを作成中です。 データの文字列に含まれる改行が、クライアントに表示された際に反映されず困っています。 過去ログも調べ、近い質問はありましたが、僕とは内容が微妙に違うようで、改めて質問させていただきました。 例えば、あるテーブルのある項目に、 A B C というデータ(A,Bそれぞれの後に改行のある3行の文字列)があるとします。 これを読み込みaction form bean(と言うのですか?setter/getterを定義する関数です)を介してjspに埋め込むと、できあがるhtmlでは、 ABC と改行されずに表示されます。 htmlで改行させるには「<BR>」が必要なのかと、データ文字列に0x0dや0x0a、または0x0d+0x0aがあれば「<BR>」に置き換えてaction form bean(?)のsetterに渡してjspを作ると、今度は、 A<BR>B<BR>C と「<BR>」が文字列として表示されます。 htmlをソース表示すると、「A&lt;BR&gt;B&lt;BR&gt;C」で、親切にも「<」「>」をそれぞれ「&lt;」「&gt;」に勝手に置き換えあくまで文字列として表示してくれるようです。 試しに改行コードを「&lt;BR&gt;」に置き換えても予想通りその部分は &lt;BR&gt; とそのまま表示され、そのソースは「&amp;lt;BR&amp;gt;」でした。 「<」や「&lt;」等をそれぞれ「&lt;」「&amp;lt;」のように置き換える作業は、どこが行っているのでしょうか。 また、改行位置で改行させるにはどうすればよろしいでしょう。 OSはwindowsXPです。 無知ゆえに、つまらないことで悪戦苦闘しているのかも知れませんが、経験も浅くてよく解りません。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • 文字コード体系の違い

    こんにちわ。 mdbでテーブル定義をしたときに, ある列の「フィールドサイズ」を10としました。 そしてVB-VSFlexGridでそのテーブルへ書き込む処理を 作り,グリッドの入力桁数を「.EditMaxLength」プロパティ で制限しようとしました。 ところが「.EditMaxLength」=10とすると, 実際の画面では全角5文字しか入力できません。 でもmdb直接入力すると,全角10文字入ってくれます。 この違いは何が原因なのでしょうか? 教えてください。お願いします。

  • 文字型フィールドの数値データの抽出

    mdbファイルを、VB6.0+ADO2.7で扱っています。 文字型フィールドに数値データが入力されたレコードを抽出したいのですが、何かよい方法はないでしょうか? そのフィールドに文字型データが入力されているレコードもあり、それを除外したいのです。 SQLでも、.filterプロパティでも結構です。お知恵を下さい。 よろしくお願いします。

  • dosのバッチ処理にて

    winのDosにてバッチ処理をする際に処理中にコマンド入力を受付け、 入力されたデータを他のコマンドパラメータに設定することって 可能でしょうか?

このQ&Aのポイント
  • スキャンができなくなった際に表示される「PCとの接続を確認してください」メッセージについて解説します。
  • EPSON社製品の中でもスキャン機能を持つ製品では、時々「PCとの接続を確認してください」というメッセージが表示されることがあります。
  • しかし、実際にはPCとの接続は正常であり、他の原因が原因でスキャンができない場合もあります。
回答を見る