- mb_convert_encoding: documentation ( source)
- mb_list_encodings: documentation ( source)
- trim: documentation ( source)
- json_encode: documentation ( source)
<?php
declare(strict_types=1);
class Escaper
{
protected $encoding;
public function __construct(string $encoding)
{
$this->encoding = $encoding;
}
public function js(string $input) : string
{
// json_encode can only accept UTF-8 encoded strings.
if ($this->encoding !== 'UTF-8') {
$input = mb_convert_encoding($input, 'UTF-8', $this->encoding);
}
$json = json_encode($input, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
if (!$json) {
return '';
}
$json = trim($json, '"');
// Convert back from UTF-8 if necessary.
if ($this->encoding !== 'UTF-8') {
//try {
$json = mb_convert_encoding($json, $this->encoding, 'UTF-8');
//} catch (Error $e) {
// echo 'ERROR CAUGHT. ENCODING: ' . $this->encoding;
// return '';
//}
}
return $json;
}
}
$malicious = 'alert("foo");</script>';
$malicious = 'test';
$utf = new Escaper('UTF-8');
$iso = new Escaper('ISO-8859-1');
echo $utf->js($malicious);
echo "\n";
echo $iso->js($malicious);
echo "\n";
foreach (mb_list_encodings() as $encoding) {
$e = new Escaper($encoding);
echo $e->js($malicious);
echo ' (' . $encoding . ')';
echo "\n";
}
/*
mb_internal_encoding('ArmSCII-8');
mb_http_output('ArmSCII-8');
$e = new Escaper('ArmSCII-8');
echo $e->js($malicious);
*/