¿Por qué se permite ejecutar código Java en comentarios con ciertos caracteres Unicode?

1366
Reg 2015-06-09 23:02.

El siguiente código produce la salida "¡Hola mundo!" (no, en serio, pruébalo).

public static void main(String... args) {

   // The comment below is not a typo.
   // \u000d System.out.println("Hello World!");
}

La razón de esto es que el compilador de Java analiza el carácter Unicode \u000dcomo una nueva línea y se transforma en:

public static void main(String... args) {

   // The comment below is not a typo.
   //
   System.out.println("Hello World!");
}

Por lo tanto, se "ejecuta" un comentario.

Dado que esto se puede utilizar para "ocultar" código malicioso o cualquier cosa que un programador malvado pueda concebir, ¿por qué está permitido en los comentarios ?

¿Por qué lo permite la especificación de Java?

7 answers

747
aioobe 2015-06-09 23:13.

La decodificación Unicode tiene lugar antes que cualquier otra traducción léxica. El beneficio clave de esto es que hace que sea trivial ir y venir entre ASCII y cualquier otra codificación. ¡Ni siquiera necesita averiguar dónde comienzan y terminan los comentarios!

Como se indica en la Sección 3.3 de JLS, esto permite que cualquier herramienta basada en ASCII procese los archivos fuente:

[...] El lenguaje de programación Java especifica una forma estándar de transformar un programa escrito en Unicode en ASCII que cambia un programa a una forma que pueda ser procesada por herramientas basadas en ASCII. [...]

Esto brinda una garantía fundamental para la independencia de la plataforma (independencia de los conjuntos de caracteres admitidos) que siempre ha sido un objetivo clave para la plataforma Java.

Poder escribir cualquier carácter Unicode en cualquier lugar del archivo es una característica interesante, y especialmente importante en los comentarios, cuando se documenta el código en idiomas no latinos. El hecho de que pueda interferir con la semántica de formas tan sutiles es solo un efecto secundario (desafortunado).

Hay muchas trampas en este tema y Java Puzzlers de Joshua Bloch y Neal Gafter incluyó la siguiente variante:

¿Es este un programa Java legal? Si es así, ¿qué imprime?

\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020
\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0067\u006c\u0079
\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020
\u0020\u0020\u0020\u0020\u0073\u0074\u0061\u0074\u0069\u0063
\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028
\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0020
\u0020\u0020\u0020\u0020\u0061\u0072\u0067\u0073\u0029\u007b
\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074
\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0020
\u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u0022\u002b
\u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u007d\u007d

(Este programa resulta ser un programa simple de "Hola mundo").

En la solución del rompecabezas, señalan lo siguiente:

Más en serio, este rompecabezas sirve para reforzar las lecciones de los tres anteriores: los escapes Unicode son esenciales cuando necesita insertar caracteres que no se pueden representar de ninguna otra manera en su programa. Evítelos en todos los demás casos.


Fuente: Java: ¿Ejecutando código en comentarios?

142
Holger 2015-06-10 07:59.

Dado que esto aún no se ha abordado, aquí una explicación, por qué la traducción de los escapes Unicode ocurre antes de cualquier otro procesamiento de código fuente:

La idea detrás de esto era que permite traducciones sin pérdidas del código fuente de Java entre diferentes codificaciones de caracteres. Hoy en día, existe un soporte generalizado de Unicode, y esto no parece un problema, pero en ese entonces no era fácil para un desarrollador de un país occidental recibir un código fuente de su colega asiático que contiene caracteres asiáticos, haga algunos cambios ( incluyendo compilarlo y probarlo) y devolver el resultado, todo sin dañar algo.

Por lo tanto, el código fuente de Java se puede escribir en cualquier codificación y permite una amplia gama de caracteres dentro de identificadores, caracteres y Stringliterales y comentarios. Luego, para transferirlo sin pérdidas, todos los caracteres no admitidos por la codificación de destino son reemplazados por sus escapes Unicode.

Este es un proceso reversible y el punto interesante es que la traducción puede realizarse con una herramienta que no necesita saber nada sobre la sintaxis del código fuente de Java, ya que la regla de traducción no depende de ella. Esto funciona ya que la traducción a sus caracteres Unicode reales dentro del compilador también ocurre independientemente de la sintaxis del código fuente de Java. Implica que puede realizar una cantidad arbitraria de pasos de traducción en ambas direcciones sin cambiar el significado del código fuente.

Esta es la razón de otra característica extraña que ni siquiera se ha mencionado: la \uuuuuuxxxxsintaxis:

Cuando una herramienta de traducción está escapando caracteres y encuentra una secuencia que ya es una secuencia escapada, debe insertar un adicional uen la secuencia, convirtiendo \ucafea \uucafe. El significado no cambia, pero cuando se convierte en la otra dirección, la herramienta solo debe eliminar una uy reemplazar solo las secuencias que contienen una upor sus caracteres Unicode. De esa manera, incluso los escapes Unicode se conservan en su forma original al realizar conversiones de ida y vuelta. Supongo que nadie usó esa función ...

108
Pepijn Schmitz 2015-06-11 07:37.

Voy a agregar de manera completamente ineficaz el punto, solo porque no puedo ayudarme a mí mismo y aún no lo he visto hecho, que la pregunta no es válida ya que contiene una premisa oculta que es incorrecta, es decir, que el código está en ¡un comentario!

En Java, el código fuente \ u000d es equivalente en todos los sentidos a un carácter ASCII CR. Es un final de línea, simple y llanamente, donde sea que ocurra. El formato de la pregunta es engañoso, a qué corresponde sintácticamente esa secuencia de caracteres es:

public static void main(String... args) {
   // The comment below is no typo. 
   // 
 System.out.println("Hello World!");
}

En mi humilde opinión, la respuesta más correcta es, por tanto: el código se ejecuta porque no está en un comentario; está en la siguiente línea. "Ejecutar código en comentarios" no está permitido en Java, tal como es de esperar.

Gran parte de la confusión se debe al hecho de que los resaltadores de sintaxis y los IDE no son lo suficientemente sofisticados como para tener en cuenta esta situación. O no procesan los escapes Unicode en absoluto, o lo hacen después de analizar el código en lugar de antes, como javachace.

69
zwol 2015-06-10 05:16.

El \u000descape finaliza un comentario porque los \uescapes se convierten uniformemente a los caracteres Unicode correspondientes antes de que el programa sea tokenizado. Se podría utilizar igualmente \u0057\u0057en lugar de //a comenzar un comentario.

Este es un error en su IDE, que debe resaltar la sintaxis de la línea para dejar claro que \u000dtermina el comentario.

Esto también es un error de diseño en el idioma. No se puede corregir ahora, porque eso rompería los programas que dependen de él. \uLos escapes deben ser convertidos al carácter Unicode correspondiente por el compilador solo en contextos donde eso "tenga sentido" (cadenas literales e identificadores, y probablemente en ningún otro lugar) o se les debería haber prohibido generar caracteres en el rango U + 0000–007F , o ambos. Cualquiera de esas semánticas habría evitado que el comentario terminara con el \u000descape, sin interferir con los casos en los que los \uescapes son útiles; tenga en cuenta que eso incluye el uso de \uescapes dentro de los comentarios como una forma de codificar los comentarios en una escritura no latina, porque el El editor de texto podría tener una visión más amplia de dónde los \uescapes son importantes que el compilador. (Sin embargo, no conozco ningún editor o IDE que muestre los \uescapes como los caracteres correspondientes en ningún contexto).

Hay un error de diseño similar en la familia C, 1 donde se procesa la barra invertida-nueva línea antes de que se determinen los límites de los comentarios, por ejemplo,

// this is a comment \
   this is still in the comment!

Menciono esto para ilustrar que resulta fácil cometer este error de diseño en particular y no darse cuenta de que es un error hasta que es demasiado tarde para corregirlo, si está acostumbrado a pensar en la tokenización y analizar la forma en que piensan los programadores de compiladores. sobre tokenización y análisis. Básicamente, si ya ha definido su gramática formal y luego alguien presenta un caso especial sintáctico: trígrafos, barra invertida-nueva línea, codificación de caracteres Unicode arbitrarios en archivos fuente limitados a ASCII, lo que sea, eso debe encajar, es más fácil de agregue un pase de transformación antes del tokenizador que redefinir el tokenizador para prestar atención a dónde tiene sentido usar ese caso especial.

1 Para los pedantes: Soy consciente de que este aspecto de C fue 100% intencional, con la justificación, no lo estoy inventando, de que le permitiría forzar mecánicamente el código con líneas arbitrariamente largas en tarjetas perforadas. Seguía siendo una decisión de diseño incorrecta.

22
Jonathan Gibbons 2015-06-10 08:45.

Esta fue una elección de diseño intencional que se remonta al diseño original de Java.

Para aquellas personas que preguntan "¿quién quiere escapes Unicode en los comentarios?", Supongo que son personas cuya lengua materna utiliza el conjunto de caracteres latinos. En otras palabras, es inherente al diseño original de Java que la gente pueda usar caracteres Unicode arbitrarios siempre que sea legal en un programa de Java, por lo general en comentarios y cadenas.

Podría decirse que es una deficiencia en los programas (como los IDE) utilizados para ver el texto fuente que dichos programas no pueden interpretar los escapes Unicode y mostrar el glifo correspondiente.

21
ZhongYu 2015-06-10 06:47.

Estoy de acuerdo con @zwol en que esto es un error de diseño; pero soy aún más crítico con eso.

\uescape es útil en literales de cadena y char; y ese es el único lugar donde debería existir. Debe manejarse de la misma manera que otros escapes como \n; y "\u000A" debería significar exactamente "\n".

No tiene absolutamente ningún sentido tener \uxxxxcomentarios, nadie puede leer eso.

Del mismo modo, no tiene sentido usarlo \uxxxxen otra parte del programa. La única excepción es probablemente en las API públicas que están obligadas a contener algunos caracteres no ascii. ¿Cuál es la última vez que lo hemos visto?

Los diseñadores tuvieron sus razones en 1995, pero 20 años después, esta parece ser una elección incorrecta.

(pregunta a los lectores: ¿por qué esta pregunta sigue obteniendo nuevos votos? ¿Esta pregunta está vinculada desde algún lugar popular?)

11
Martijn 2015-06-13 01:59.

Las únicas personas que pueden responder por qué se implementaron los escapes Unicode como estaban son las personas que escribieron la especificación.

Una razón plausible para esto es que existía el deseo de permitir el BMP completo como caracteres posibles del código fuente de Java. Sin embargo, esto presenta un problema:

  • Quieres poder usar cualquier carácter BMP.
  • Desea poder ingresar cualquier carácter de BMP de manera razonablemente fácil. Una forma de hacer esto es con los escapes Unicode.
  • Desea que la especificación léxica sea fácil de leer y escribir para los humanos, y también razonablemente fácil de implementar.

Esto es increíblemente difícil cuando los fugas Unicode entran en juego: crea una gran cantidad de nuevas reglas de lexer.

La salida más fácil es hacer lexing en dos pasos: primero busque y reemplace todos los escapes Unicode con el carácter que representa, y luego analice el documento resultante como si los escapes Unicode no existieran.

La ventaja de esto es que es fácil de especificar, por lo que simplifica la especificación y es fácil de implementar.

La desventaja es, bueno, tu ejemplo.

Related questions

MORE COOL STUFF

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

¿Caduca el repelente de insectos?

¿Caduca el repelente de insectos?

¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?

Estados Unidos podría evitarse el horror del nuevo gran horneado británico

Estados Unidos podría evitarse el horror del nuevo gran horneado británico

Si este tráiler de pesadilla de la temporada más reciente de Great British Bake Off te asustó y te hizo no volver a ver el programa, es posible que tengas suerte: PBS no ha decidido si se transmitirá o no la última temporada en los Estados Unidos. actualización, para aquellos que no siguen sin aliento este tipo de drama de nicho: el presentador Paul Hollywood y la hermosa carpa llena de batidoras de colores pastel y cuadros se trasladaron de la BBC al Canal 4; Mary Berry, Sue Perkins y Mel Giedroyc renunciaron.

Atún como Oh, Hello llega a Netflix

Atún como Oh, Hello llega a Netflix

Foto: Netflix Oh, Hello On Broadway (Netflix): Después de llegar a Broadway el año pasado, los dos locos del Upper West Side interpretados por John Mulaney y Nick Kroll finalmente llegaron a Netflix. El especial consta del espectáculo en el escenario, algunos momentos entre bastidores y un invitado muy especial de “Too Much Tuna”.

Actualice a un Sonicare por tan solo $ 30

Actualice a un Sonicare por tan solo $ 30

¿Quiere probar un cepillo de dientes Sonicare sin gastar mucho dinero en uno de sus modelos favoritos de gama alta? Puede comprar un kit de la Serie 2 o Serie 3 por tan solo $ 30 hoy en Amazon. Haga clic aquí para ver la lista completa de modelos elegibles y tenga en cuenta que se descontarán $ 10 adicionales en su carrito.

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.

India me está pateando el culo

India me está pateando el culo

Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

¿Merrick Garland le ha fallado a Estados Unidos?

Es más de la mitad de la presidencia de Biden. ¿Qué está esperando Merrick Garland?

¿Merrick Garland le ha fallado a Estados Unidos?

Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.

Language