20

わかりました。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文字をどのように削除/エスケープしますか?

どうもありがとう。

4

2 に答える 2

22

PHP側またはJavaScript側、あるいはその両方でU+2028U+2029をに置き換えることができます。少なくとも1回発生する限り、問題はありません(べき等です)。"\u2028""\u2029"

通常の文字列置換関数を使用できます。これらは「マルチバイトセーフ」である必要はなく、どのUnicodeエンコーディングでも同じように簡単に実行できます(UTF-8、UTF-16、UTF-32はすべて同じように問題ありません)。前回チェックしたとき、PHPにはUnicodeエスケープシーケンスがありませんでした。これが、PHPが冗談であるもう1つの理由ですが\x、UTF-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はデフォルトで非Unicode文字を次のようにエスケープするため、何もすることはできませんjson_encode()

// 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);
--> "
"
于 2013-01-06T04:57:24.553 に答える
1

これはもはや必要ではないことを指摘する価値があります。

デフォルトでは、すべてのjson_encode()非ASCII文字(U+2028およびU+2029を含む)をエンコードし、JSON仕様でエスケープする必要がない場合でも、スラッシュもエスケープします。それを逃れることは害はなく、特定の状況ではより安全になる可能性があります。したがって、デフォルトでは、これらの文字はとにかくエスケープされます。

定数はJSON_UNESCAPED_UNICODEエスケープされていないUnicodeを出力し、バイトを節約できます。ただし、スラッシュ文字が一部のコンテキストで危険である可能性があるためにエスケープされるのと同様に、U+2028およびU+2029一部のコンテキストで危険であるため、エスケープされます。あなたが質問をしたときはそうではありませんでした:この機能は最近PHPに追加されました

JSON_UNESCAPED_SLASHES(これらの追加のエスケープは、とでそれぞれオフにすることができますJSON_UNESCAPED_LINE_TERMINATORS。)

于 2017-07-14T16:35:54.437 に答える