わかりました。データがPHPサーバーから提供されるパブリックJSONPAPIを実行しています。この記事を読んだばかりです。
基本的に、JSON文字列にU + 2028文字(Unicode行区切り文字)またはU + 2029文字(Unicode段落区切り文字)が含まれている場合、これは完全に有効なJSONです。ただし、JSONPを使用する場合、JSONはJavaScriptとして実行され、JavaScriptを壊すため、JavaScriptの文字列にリテラルU +2028またはU + 2029を含めることはできません。どうやら、適切なJSONパーサーを使用している限り、これは通常問題ではありませんが、JSONPの場合、ブラウザーはJSONパーサーです。
基本的に、これらの文字がクライアントに送信されるJSONPデータの文字列内にある場合、これにより文字列に行または段落の区切りがスローされ、JavaScriptが破損して実行が停止します。これは、APIがクライアントが入力したデータを送り返す可能性があるためです。誰かがU + 2028またはU + 2029をデータベースに入力する可能性があるため、それをJSONPとして返送すると、APIを使用した実装が破損します。
だから私の質問は、PHPでJSONデータをサニタイズ/出力エスケープして、クライアントに送信する前にU +2028およびU + 2029文字を削除またはエスケープするにはどうすればよいですか?
現在、私のプロセスはデータの配列に対して json_encode を実行し、そのデータをクライアントに送信しています。配列をループしてフィルタリングすることでデータをエスケープする必要がありますか、それともすべてのJSONエンコード文字列を一度にエスケープする必要がありますか?
もう1つは、PHP)のU +2028文字とU + 2029文字をエスケープする方法がわからないことです。str_replaceを実行できますか?str_replaceがマルチバイトかどうかわかりません。安全で、カスタムメイドの関数を使用しない限り、 mb_str_replaceなし 関数があります。では、これらのUnicode文字をどのように削除/エスケープしますか?
どうもありがとう。
PHP側またはJavaScript側、あるいはその両方で、U+2028
、U+2029
を"\u2028"
、"\u2029"
に置き換えることができます。少なくとも1回発生する限り、問題ではありません(べき等です)。
通常の文字列置換関数を使用できます。これらは「マルチバイトセーフ」である必要はなく、どのUnicodeエンコーディングでも同じように簡単に実行できます(UTF-8、UTF-16、UTF-32はすべて同じように問題ありません)。 PHP前回チェックしたときにUnicodeエスケープシーケンスがありませんでした。これは、PHPが冗談ですが、UTFで\x
エスケープを使用できるもう1つの理由です。 -8.。
(要するに、マルチバイト文字列置換関数がない理由は、冗長になるためです。非マルチバイト文字列置換関数とまったく同じになります。)
// Javascript
data = data.replace("\u2028", "\\u2028").replace("\u2029", "\\u2029");
// PHP
$data = str_replace("\xe2\x80\xa8", '\\u2028', $data);
$data = str_replace("\xe2\x80\xa9", '\\u2029', $data);
または、PHPはデフォルトでjson_encode()
で非Unicode文字をエスケープするため、何もすることはできません。
// Safe
echo json_encode("\xe2\x80\xa9");
--> "\u2029"
// Correct JSON, but invalid Javascript...
// (Well, technically, JSON root must be array or object)
echo json_encode("\xe2\x80\xa9", JSON_UNESCAPED_UNICODE);
--> "
"
これはもはや必要ないことを指摘する価値があります。
デフォルトでは、 json_encode()
はall非ASCII文字(U +2028およびU + 2029を含む)をエンコードします)、また、JSON仕様でエスケープする必要がない場合でも、スラッシュをエスケープします。それを逃れることは害はなく、特定の状況ではより安全になる可能性があります。したがって、デフォルトでは、これらの文字はとにかくエスケープされます。
JSON_UNESCAPED_UNICODE
定数は、エスケープされていないUnicodeを出力します。これにより、バイトを節約できます。ただし、状況によっては危険な場合があるためスラッシュ文字がエスケープされるのと同じように、U +2028とU + 2029もまたエスケープされます。それらも状況によっては危険です。あなたが質問をしたときはそうではありませんでした: この機能はPHP最近 に追加されました。
(これらの追加のエスケープは、それぞれJSON_UNESCAPED_SLASHES
およびJSON_UNESCAPED_LINE_TERMINATORS
でオフにできます。)