Tengo una cadena y necesito asegurarme de que contenga solo una expresión regular y no javascript porque estoy creando un nuevo script con la cadena para que un fragmento de javascript sea un riesgo de seguridad.

Escenario exacto:

  1. JS en el complemento de mozilla carga la configuración como json a través de HTTPrequest (json contiene {"algo": "^ (?: Http | https): // (?:. *)"}
  2. JS crea un archivo pac (script de configuración de proxy) que usa la expresión regular "algo" de la configuración

¿Alguna idea de cómo escapar de la cadena sin destruir la expresión regular en ella?

0
Malte Goetz 28 ago. 2014 a las 19:33

2 respuestas

La mejor respuesta

Parece que la mayoría de las funciones estándar de JavaScript están disponibles (fuente), así que puedes hacer:

try {
    RegExp(json.something+'');
    pacFile += 'RegExp(' + JSON.stringify(json.something+'') + ')';
} catch(e) {/*handle invalid regexp*/}

Y no se preocupe, porque un RegExp("console.log('test')") solo producirá una expresión regular /console.log('test')/ válida y no ejecutará nada.

0
Volune 28 ago. 2014 a las 18:25

Puede usar una expresión regular para separar una expresión regular de JavaScript.

Luego, debe convertir la expresión regular en un subconjunto léxico más simple de JavaScript que evite todas las rarezas sin contexto sobre lo que significa /, y cualquier irregularidad en la expresión regular de entrada.

var REGEXP_PARTS = "(?:"
    // A regular character
    + "[^/\r\n\u2028\u2029\\[\\\\]"
    // An escaped character, charset reference or backreference
    + "|\\\\[^\r\n\u2028\u2029]"
    // A character set
    + "|\\[(?!\\])(?:[^\\]\\\\]|\\\\[^\r\n\u2028\u2029])+\\]"
    + ")";

var REGEXP_REGEXP = new RegExp(
    // A regex starts with a slash
    "^[/]"
    // It cannot be lexically ambiguous with a line or block comemnt
    + "(?![*/])"
    // Capture the body in group 1
    + "(" + REGEXP_PARTS + "+)"
    // The body is terminated by a slash
    + "[/]"
    // Capture the flags in group 2
    + "([gmi]{0,3})$");

 var match = myString.match(REGEXP_REGEXP);

 if (match) {
   var ctorExpression =
       "(new RegExp("
         // JSON.stringify escapes special chars in the body, so will
         // preserve token boundaries.
         + JSON.stringify(match[1])
         + "," + JSON.stringify(match[2])
       + "))";
   alert(ctorExpression);
 }

Lo que dará como resultado una expresión que se encuentra en un subconjunto bien comprendido de JavaScript.

La expresión regular compleja anterior no se encuentra en TCB. La única parte que debe funcionar correctamente para que la seguridad se mantenga es ctorExpression, incluido el uso de JSON.stringify.

0
Mike Samuel 28 ago. 2014 a las 18:09