12

ユーザーがフォームにテキストを入力するアプリケーションがあります。

データはMySQLデータベースに保存され(照合:) utf8_general_ci、XMLとして出力されます(エンコード:UTF-8)。

問題は、Microsoft WordドキュメントやPDFなど、他のソースから情報を切り取って貼り付ける傾向があることです。

この入力テキストには、 Windows-1252エンコーディングのドキュメントに由来する「スマートクォート」など、出力エンコーディングに対して正しくない文字が含まれていることがよくあります。

これは、文字が不正であるため、XMLを変換したり、その他の方法で作業したりするときに、明らかに問題を引き起こします。

では、入力をサニタイズする方法は?

以前は、検索と置換操作の長いリストで構成される「de-moronize」スクリプトなど、かなり力ずくの方法を使用していました。

これはまだそれを行うための最良の方法ですか?他に方法はありますか?

フォームにaccept-charset属性を設定して、ブラウザにそれを実行させることはできますか?

もしそうなら、どのブラウザがそれを行い、問題が発生する可能性がありますか?

また、データベースがUTF-8で予約/制御文字であるこれらの文字を受け入れるのはなぜですか?

ご覧のとおり、私はエンコーディングについて十分に知っているので、問題があることを知っていますが、今は少し深みがありません...

TIA

4

3 に答える 3

9

この入力テキストには、多くの場合、Windows-1252 エンコーディングのドキュメントに由来する「スマート クォート」など、出力エンコーディングには不適切な文字が含まれています。

「スマート クォート」 (cp1252 のバイト 147 と 148) は、完全に有効な Unicode 文字、U+201C と U+201D です。アプリケーションはそれらをシームレスに処理できる必要があります。そうでない場合は、何か間違ったことをしており、おそらくすべての非 ASCII 文字が失敗します。

文字が入力されたものか、Word から貼り付けられたものかに関係なく、ブラウザは UTF-8 でエンコードされた文字をアプリケーションに送信する必要があり、アプリケーションは同じ UTF-8 バイトをデータベースに保存する必要があります。

ブラウザーが UTF-8 で送信しない場合、フォームを含む HTML ページの文字セットを設定していない可能性があります。これは、次を使用して実行できます。

Content-Type: text/html;charset=utf-8

HTTP ヘッダーおよび/または:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

<head> 内の要素。

フォームに accept-charset 属性を設定するだけで、ブラウザにそれを実行させることはできますか?

いいえ、accept-charset は IE のおかげで基本的に役に立ちません。IE は、「常にこの文字セットを使用する」のではなく、「ページ上の文字セットが必要な文字をエンコードできない場合は、この文字セットを使用してみてください」と誤解します。これは、accept-charset を使用すると、一度に送信されたエンコーディングが混在することになり、どれがどれであるかを判断する方法がないことを意味します。良い!

データベースが UTF-8 の予約/制御文字であるこれらの文字を受け入れるのはなぜですか?

MySQL では、UTF-8 は単なる照合であり、比較と順序付けに使用されます。データはまだバイトとして保存されており、有効な UTF-8 シーケンスでないかどうかは気にしません。

いずれにせよ、受信した UTF-8 シーケンスをアプリでデコードしてチェックすることをお勧めします。これは、最新の Unicode では無効な「短いシーケンス」が「<」を隠す可能性があるためです。古いブラウザ (少なくとも SP2 より前の IE6、Opera 7) でも認識される文字。

到着予定時刻:

というわけで、バイト146を含む文字列を入力しました

いいえ、Unicode 文字 U+201B を入力しました。ブラウザーは、シリアル化されたフォームをサーバーに送信する必要がある時点まで、バイトではなく Unicode 文字を処理します。次に、文字をバイトに変換する方法を決定し、ページが UTF-8 として処理されている場合は、常に UTF-8 を選択します。

(UTF-8 でない場合、ブラウザは標準に準拠しない方法でごまかす傾向があります。エンコーディングに収まらないすべての文字については、「&#8217;」のような HTML 文字参照にエンコードします。ブラウザがエスケープした '&' と実際のユーザーが入力した '&' の違いがわからないため、これは間違っています。また、参照をエスケープされていない HTML としてエコーすると、正しく理解しているかのように、実際には大きな古いセキュリティ ホールを作成しただけです。)

146としてデータベースに入りました

本当に、'\xC2\x92'、'\xE2\x80\x99'、'’' ではなく、'\x92' バイトですか?

(UTF-8 でエンコードされた) XML を 146 として作成したときに出てきました。ブラウザーからの苦情はありません。

その後、単一の 146 バイトとして出力されませんでした。XML ファイルでそのままの '\x92' を指定すると、ブラウザーはエラーを出します。(無効な UTF-8 シーケンスが欠落文字グリフとして表示される HTML ファイルではありません。)

「&#146;」として出てくるのではないかと思います。整形式の文字参照 (ただし、文字 U+0092 は C1 コントロール セットの一部であるため、有用なものとしてレンダリングされません)。これが起こっている場合、フォーム ページは結局 UTF-8 として認識されず、上記のブラウザの自動エスケープ送信の問題に苦しんでいます。

于 2009-04-15T12:32:22.263 に答える
2

PerlEncodeモジュールを試してみてください。これは、couseのUTF-8を含む、多数の文字セット間の変換をサポートします。Perlのインストールを確認したところ、ウィキペディアによるとWindows-1252の別名である「cp1252」もサポートされていました。次のワンライナーで自分のインストールを確認できます。

perl -MEncode -e 'print map {"$_\n"} Encode->encodings(":all");'
于 2009-04-15T03:01:40.870 に答える
1

「フォームに accept-charset 属性を設定して、ブラウザに設定してもらうことはできますか?」

「ブラウザ」を信頼する準備ができている場合のみ - 一部のアプリケーションには適しているかもしれませんが、一般的には、いたずら (またはさらに悪いこと) にさらされる可能性があります。

(IEに関するボビンスの警告も参照してください...)

イアン

于 2009-04-16T02:48:17.510 に答える