与えられた情報では、ここで問題を引き起こしているのは esapi ではありません。次の単体テストに合格します。
@Test
public void testWindowsNewline() {
Encoder instance = ESAPI.encoder();
assertEquals("\\x0D\\x0A", instance.encodeForJavaScript("\r\n"));
}
FWIW、taglibs は esapi エンコーダー クラスの単なるラッパーです。
JavaScript 文字列に埋め込まれた taglibs を使用しているようです。これは、私のチームのコード レビューで見た場合、欠陥としてマークします。その理由は次のとおりです。
ページをレンダリングするときに JSP コンパイラが実行する手順は複数あります。ほんの数例を挙げると、HTML レンダリング、データ バインディング、JSTL バインディングがあります。この順序付けは実装固有であるため、ここにあるようなコードを混在させないようにしてください。
を呼び出す前に、JSP コンパイラが"\r\n"
を HTML 空白として解釈していると思われます<esapi:encodeForJavaScript></esapi:encodeForJavaScript>
。
ここに私が過去にやったことのいくつかがあります。私はコントローラー/サービス層でのエスケープを好む傾向があります。この例では、Spring MVC を想定しており、かなりの自由を取っています。
@Controller
public class FooController {
//This should actually be done in a service class, but this is for demo
private Encoder = ESAPI.encoder();
@Autowired
private DataService dataService;
//logic for handling request
public String returnStringEscapedForJavascriptContext(){
OrderBean myOrder = dataService.getMyOrder();
String unescaped = myOrder.getRateErrorMessage();
String escapedAsJavascriptData = encoder.encodeForJavaScript(unescaped);
return escapedAsJavascriptData ;
}
}
myOrder
viewBean などに 変換する場合も、同じ基本的なロジックが適用されます。
もう 1 つの解決策は、安全な esapi エスケープ メソッドを、すべてのビュー Bean が継承した抽象クラスとしてラップすることです。そのため、JSP でこの作業を本当に行う必要がある場合は、次のようにすることができます。
public abstract class SecureBean {
private Encoder encoder = ESAPI.encoder();
public String escapeForJavaScript(String input){
return encoder.escapeForJavaScript(input);
}
}
次に継承します。
public class OrderBean extends SecureBean {
String rateErrorMessage; //with getters/setters assumed
}
今あなたのjspで:
var errReason= '${myOrder.escapeForJavaScript(myOrder.rateErrorMessage())}';
一部は少し冗長ですが、ここでの目標は、JSP のレンダリング順序を踏まないようにすることです。Encoder の実装を交換できるように、エンコード/デコード用のアダプター インターフェイスを作成することも検討してください。