Iconos SCW
héroe bg sin separador
Blog

Java: Trampas - Operadores bit a bit y operadores booleanos

Alan Richardson
Publicado el 07 de febrero de 2021
Última actualización el 9 de marzo de 2026

Java: Trampas - Operadores bit a bit y operadores booleanos

«Java Gotcha»: un patrón de error común que se produce fácilmente de forma inesperada.

Un problema bastante sencillo de Java que puede surgir inesperadamente es el uso de operadores bit a bit en lugar de operadores de comparación booleanos.

Por ejemplo, cuando realmente quieres escribir «&&», un simple error de entrada puede provocar que se escriba «&».

Los métodos heurísticos comunes que aprendemos al revisar el código son:

El uso de «&» o «|» en una cláusula condicional puede no ser intencionado.

En esta entrada del blog, exploraremos métodos heurísticos y determinaremos formas de identificar y corregir este problema de codificación.


¿Dónde está el problema? El uso de operaciones booleanas permite realizar operaciones bit a bit correctamente.


El uso de operadores bit a bit con valores booleanos es totalmente válido, por lo que Java no informa de ningún error sintáctico.

Si construyo una prueba JUnit para explorar la tabla de valores verdaderos de la operación bit a bit (|) y la operación bit a bit (&), veremos que la salida del operador bit a bit coincide con la tabla de valores verdaderos. Teniendo esto en cuenta, podríamos pensar que el uso del operador bit a bit no supone ningún problema.

Y tabla de verdades

Tres columnas una con a, otra con b, y la última con (a^b)


@Test
void Operador bit a bit y TruthTable () {
assertions.asserteQuals(verdadero, verdadero y verdadero);
assertions.asserteQuals(falso, verdadero y falso);
assertions.asserteQuals(falso, falso y verdadero);
assertions.asserteQuals(falso, falso y falso);
}


La prueba ha sido superada, es Java totalmente válido.


OR Tabla de verdades


Tres columnas sobre con a, una con b, y la última con (a v b)


@Test
void Operador bit a bit o tabla de valores verdaderos () {
assertions.asserteQuals(verdadero, verdadero | verdadero);
assertions.asserteQuals(verdadero, verdadero | falso);
assertions.asserteQuals(verdadero, falso | verdadero);
assertions.asserteQuals(falso, falso | falso);
}


Esta prueba también ha sido superada, ¿por qué preferimos «&&» y «||»?


La tabla de verdad es una herramienta creada para herramienta de tabla de verdad de web.standfor.edu.


Pregunta: Operación de cortocircuito


El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).

Los operadores booleanos son operadores de cortocircuito y solo se evalúan cuando es necesario.

Por ejemplo

if (args!= null & args.length () > 23) {
system.out.println (args);
}


En el código anterior, se evaluarán ambas condiciones booleanas, ya que se utiliza el operador bit a bit:

  • args!= valor vacío
  • args.length () > 23

Si args está vacío, esto expone mi código al riesgo de NullPointerException, ya que incluso si el parámetro está vacío, siempre comprobaremos args.length, ya que hay que evaluar dos condiciones booleanas.


Evaluación de cortocircuito del operador booleano


Cuando se utiliza &&, por ejemplo

if (args!= null && args.length () > 23) {
system.out.println (args);
}


Si sabemos que args != null, el resultado del cálculo es falso y el cálculo de la expresión condicional se detiene.

No necesitamos evaluar la derecha.

Independientemente del resultado de la condición de la derecha, el valor final de la expresión booleana será falso.


Pero esto nunca ocurre en el código de producción.


Este es un error fácil de cometer, y las herramientas de análisis estático no siempre lo cometen.

Utilicé el siguiente Google Dork para ver si podía encontrar algún ejemplo público de este patrón:

Tipo de archivo: java if “!=null &”
Esta búsqueda ha encontrado código de Android en rootwindowContainer
isDocument = ¡Intención! = null & intent.isDocument ()


Este código podría pasar la revisión de código, ya que a menudo utilizamos operadores bit a bit en sentencias de asignación para enmascarar valores. Sin embargo, en este caso, el resultado es el mismo que en el ejemplo anterior con la sentencia if. Si intent siempre está vacío, se lanzará una excepción NullPointerException.

A menudo escapamos de esta estructura porque solemos realizar codificación defensiva y escribir código redundante. El cheque != null probablemente sea innecesario en la mayoría de los casos de uso.

Este es un error cometido por los programadores en el código de producción.

No sé qué tan recientes son los resultados de búsqueda, pero cuando realizo una búsqueda, los códigos que aparecen en los resultados provienen de: Google, Amazon, Apache... y yo.

Las últimas solicitudes de extracción en uno de mis proyectos de código abierto tienen como objetivo resolver este error.

if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}


¿Cómo encontrar esto?


Cuando revisé mi código de ejemplo en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.

Como Secure Code Warrior , hemos creado y revisado una Sensei bastante sencilla que permite resolver este problema.

Dado que los operadores bit a bit son totalmente eficaces y se utilizan con frecuencia en la asignación de valores, nos hemos centrado en estudiar los casos de uso de las sentencias if y el uso de Bitwise & para encontrar el código problemático.

搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”


Cuando se utiliza como expresión condicional, utiliza expresiones regulares para coincidir con «&». Por ejemplo, en la instrucción if.

Para solucionar este problema, volvemos a recurrir a las expresiones regulares. Esta vez, utilizamos la función sed de QuickFix para sustituir globalmente & por && en la expresión.

Soluciones disponibles:
-Nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
Acción:
-Reescribir:
Cambiar a: «{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}»


Nota al pie

Esto cubre el caso más común de uso indebido de los operadores bit a bit, es decir, cuando se utilizan operadores booleanos.

En otras circunstancias, como en los ejemplos de tareas, puede darse esta situación, pero al redactar las recetas debemos evitar en la medida de lo posible los falsos positivos, ya que, de lo contrario, las recetas se ignorarán o se cerrarán. Creamos recetas que se ajustan a las situaciones más habituales. A medida que Sensei evolucione, es muy probable que añadamos especificidad adicional a la función de búsqueda para abarcar más condiciones de coincidencia.

En su forma actual, la fórmula identificará muchos casos de uso prácticos y, lo que es más importante, el que se describe en mi proyecto.

Aviso: Muchos guerreros del código han contribuido a este ejemplo y a la revisión de la receta: Charlie Erikson, Matthew Carley, Robin Clairhout, Bryson Axe, Nathan Desmet y Donny Robershott. Gracias por vuestra ayuda.


---


Puedes instalar Sensei desde IntelliJ utilizando «Preferencias\ Complementos» (Mac) o «Configuración\ Complementos» (Windows). Sensei «código desensei

En el repositoriosensei de la cuenta Secure Code Warrior de Secure Code Warrior , tenemos el código fuente y las recetas de muchas de estas entradas del blog (incluida esta).

https://github.com/securecodewarrior/sensei-blog-examples

Sensei información sobre Sensei


Ver recursos
Ver recursos

En esta entrada del blog, exploraremos un error común en la codificación Java (el uso del operador bit a bit en lugar del operador condicional), los errores a los que nos expone nuestro código y cómo utilizar Sensei corregir y detectar problemas.

¿Te interesa saber más?

Alan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.

Más información

Secure Code Warrior puede ayudar a su organización a proteger el código a lo largo de todo el ciclo de vida del desarrollo de software y a crear una cultura que dé prioridad a la ciberseguridad. Tanto si es usted responsable de seguridad de aplicaciones, desarrollador, director de seguridad de la información o cualquier otra persona relacionada con la seguridad, podemos ayudar a su organización a reducir los riesgos asociados al código inseguro.

Reservar una demostración
Compartir en:
marcas de LinkedInSocialx logotipo
Autor
Alan Richardson
Publicado el 07 de febrero de 2021

Alan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.

Compartir en:
marcas de LinkedInSocialx logotipo

Java: Trampas - Operadores bit a bit y operadores booleanos

«Java Gotcha»: un patrón de error común que se produce fácilmente de forma inesperada.

Un problema bastante sencillo de Java que puede surgir inesperadamente es el uso de operadores bit a bit en lugar de operadores de comparación booleanos.

Por ejemplo, cuando realmente quieres escribir «&&», un simple error de entrada puede provocar que se escriba «&».

Los métodos heurísticos comunes que aprendemos al revisar el código son:

El uso de «&» o «|» en una cláusula condicional puede no ser intencionado.

En esta entrada del blog, exploraremos métodos heurísticos y determinaremos formas de identificar y corregir este problema de codificación.


¿Dónde está el problema? El uso de operaciones booleanas permite realizar operaciones bit a bit correctamente.


El uso de operadores bit a bit con valores booleanos es totalmente válido, por lo que Java no informa de ningún error sintáctico.

Si construyo una prueba JUnit para explorar la tabla de valores verdaderos de la operación bit a bit (|) y la operación bit a bit (&), veremos que la salida del operador bit a bit coincide con la tabla de valores verdaderos. Teniendo esto en cuenta, podríamos pensar que el uso del operador bit a bit no supone ningún problema.

Y tabla de verdades

Tres columnas una con a, otra con b, y la última con (a^b)


@Test
void Operador bit a bit y TruthTable () {
assertions.asserteQuals(verdadero, verdadero y verdadero);
assertions.asserteQuals(falso, verdadero y falso);
assertions.asserteQuals(falso, falso y verdadero);
assertions.asserteQuals(falso, falso y falso);
}


La prueba ha sido superada, es Java totalmente válido.


OR Tabla de verdades


Tres columnas sobre con a, una con b, y la última con (a v b)


@Test
void Operador bit a bit o tabla de valores verdaderos () {
assertions.asserteQuals(verdadero, verdadero | verdadero);
assertions.asserteQuals(verdadero, verdadero | falso);
assertions.asserteQuals(verdadero, falso | verdadero);
assertions.asserteQuals(falso, falso | falso);
}


Esta prueba también ha sido superada, ¿por qué preferimos «&&» y «||»?


La tabla de verdad es una herramienta creada para herramienta de tabla de verdad de web.standfor.edu.


Pregunta: Operación de cortocircuito


El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).

Los operadores booleanos son operadores de cortocircuito y solo se evalúan cuando es necesario.

Por ejemplo

if (args!= null & args.length () > 23) {
system.out.println (args);
}


En el código anterior, se evaluarán ambas condiciones booleanas, ya que se utiliza el operador bit a bit:

  • args!= valor vacío
  • args.length () > 23

Si args está vacío, esto expone mi código al riesgo de NullPointerException, ya que incluso si el parámetro está vacío, siempre comprobaremos args.length, ya que hay que evaluar dos condiciones booleanas.


Evaluación de cortocircuito del operador booleano


Cuando se utiliza &&, por ejemplo

if (args!= null && args.length () > 23) {
system.out.println (args);
}


Si sabemos que args != null, el resultado del cálculo es falso y el cálculo de la expresión condicional se detiene.

No necesitamos evaluar la derecha.

Independientemente del resultado de la condición de la derecha, el valor final de la expresión booleana será falso.


Pero esto nunca ocurre en el código de producción.


Este es un error fácil de cometer, y las herramientas de análisis estático no siempre lo cometen.

Utilicé el siguiente Google Dork para ver si podía encontrar algún ejemplo público de este patrón:

Tipo de archivo: java if “!=null &”
Esta búsqueda ha encontrado código de Android en rootwindowContainer
isDocument = ¡Intención! = null & intent.isDocument ()


Este código podría pasar la revisión de código, ya que a menudo utilizamos operadores bit a bit en sentencias de asignación para enmascarar valores. Sin embargo, en este caso, el resultado es el mismo que en el ejemplo anterior con la sentencia if. Si intent siempre está vacío, se lanzará una excepción NullPointerException.

A menudo escapamos de esta estructura porque solemos realizar codificación defensiva y escribir código redundante. El cheque != null probablemente sea innecesario en la mayoría de los casos de uso.

Este es un error cometido por los programadores en el código de producción.

No sé qué tan recientes son los resultados de búsqueda, pero cuando realizo una búsqueda, los códigos que aparecen en los resultados provienen de: Google, Amazon, Apache... y yo.

Las últimas solicitudes de extracción en uno de mis proyectos de código abierto tienen como objetivo resolver este error.

if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}


¿Cómo encontrar esto?


Cuando revisé mi código de ejemplo en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.

Como Secure Code Warrior , hemos creado y revisado una Sensei bastante sencilla que permite resolver este problema.

Dado que los operadores bit a bit son totalmente eficaces y se utilizan con frecuencia en la asignación de valores, nos hemos centrado en estudiar los casos de uso de las sentencias if y el uso de Bitwise & para encontrar el código problemático.

搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”


Cuando se utiliza como expresión condicional, utiliza expresiones regulares para coincidir con «&». Por ejemplo, en la instrucción if.

Para solucionar este problema, volvemos a recurrir a las expresiones regulares. Esta vez, utilizamos la función sed de QuickFix para sustituir globalmente & por && en la expresión.

Soluciones disponibles:
-Nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
Acción:
-Reescribir:
Cambiar a: «{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}»


Nota al pie

Esto cubre el caso más común de uso indebido de los operadores bit a bit, es decir, cuando se utilizan operadores booleanos.

En otras circunstancias, como en los ejemplos de tareas, puede darse esta situación, pero al redactar las recetas debemos evitar en la medida de lo posible los falsos positivos, ya que, de lo contrario, las recetas se ignorarán o se cerrarán. Creamos recetas que se ajustan a las situaciones más habituales. A medida que Sensei evolucione, es muy probable que añadamos especificidad adicional a la función de búsqueda para abarcar más condiciones de coincidencia.

En su forma actual, la fórmula identificará muchos casos de uso prácticos y, lo que es más importante, el que se describe en mi proyecto.

Aviso: Muchos guerreros del código han contribuido a este ejemplo y a la revisión de la receta: Charlie Erikson, Matthew Carley, Robin Clairhout, Bryson Axe, Nathan Desmet y Donny Robershott. Gracias por vuestra ayuda.


---


Puedes instalar Sensei desde IntelliJ utilizando «Preferencias\ Complementos» (Mac) o «Configuración\ Complementos» (Windows). Sensei «código desensei

En el repositoriosensei de la cuenta Secure Code Warrior de Secure Code Warrior , tenemos el código fuente y las recetas de muchas de estas entradas del blog (incluida esta).

https://github.com/securecodewarrior/sensei-blog-examples

Sensei información sobre Sensei


Ver recursos
Ver recursos

Rellene el siguiente formulario para descargar el informe.

Nos gustaría obtener su permiso para enviarle información sobre nuestros productos y/o temas relacionados con la codificación de seguridad. Trataremos su información personal con el máximo cuidado y nunca la venderemos a otras empresas con fines comerciales.

Enviar
Icono de éxito de SCW
Icono de error scw
Para enviar el formulario, habilite las cookies de análisis. Una vez completado, puede desactivarlas nuevamente si lo desea.

Java: Trampas - Operadores bit a bit y operadores booleanos

«Java Gotcha»: un patrón de error común que se produce fácilmente de forma inesperada.

Un problema bastante sencillo de Java que puede surgir inesperadamente es el uso de operadores bit a bit en lugar de operadores de comparación booleanos.

Por ejemplo, cuando realmente quieres escribir «&&», un simple error de entrada puede provocar que se escriba «&».

Los métodos heurísticos comunes que aprendemos al revisar el código son:

El uso de «&» o «|» en una cláusula condicional puede no ser intencionado.

En esta entrada del blog, exploraremos métodos heurísticos y determinaremos formas de identificar y corregir este problema de codificación.


¿Dónde está el problema? El uso de operaciones booleanas permite realizar operaciones bit a bit correctamente.


El uso de operadores bit a bit con valores booleanos es totalmente válido, por lo que Java no informa de ningún error sintáctico.

Si construyo una prueba JUnit para explorar la tabla de valores verdaderos de la operación bit a bit (|) y la operación bit a bit (&), veremos que la salida del operador bit a bit coincide con la tabla de valores verdaderos. Teniendo esto en cuenta, podríamos pensar que el uso del operador bit a bit no supone ningún problema.

Y tabla de verdades

Tres columnas una con a, otra con b, y la última con (a^b)


@Test
void Operador bit a bit y TruthTable () {
assertions.asserteQuals(verdadero, verdadero y verdadero);
assertions.asserteQuals(falso, verdadero y falso);
assertions.asserteQuals(falso, falso y verdadero);
assertions.asserteQuals(falso, falso y falso);
}


La prueba ha sido superada, es Java totalmente válido.


OR Tabla de verdades


Tres columnas sobre con a, una con b, y la última con (a v b)


@Test
void Operador bit a bit o tabla de valores verdaderos () {
assertions.asserteQuals(verdadero, verdadero | verdadero);
assertions.asserteQuals(verdadero, verdadero | falso);
assertions.asserteQuals(verdadero, falso | verdadero);
assertions.asserteQuals(falso, falso | falso);
}


Esta prueba también ha sido superada, ¿por qué preferimos «&&» y «||»?


La tabla de verdad es una herramienta creada para herramienta de tabla de verdad de web.standfor.edu.


Pregunta: Operación de cortocircuito


El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).

Los operadores booleanos son operadores de cortocircuito y solo se evalúan cuando es necesario.

Por ejemplo

if (args!= null & args.length () > 23) {
system.out.println (args);
}


En el código anterior, se evaluarán ambas condiciones booleanas, ya que se utiliza el operador bit a bit:

  • args!= valor vacío
  • args.length () > 23

Si args está vacío, esto expone mi código al riesgo de NullPointerException, ya que incluso si el parámetro está vacío, siempre comprobaremos args.length, ya que hay que evaluar dos condiciones booleanas.


Evaluación de cortocircuito del operador booleano


Cuando se utiliza &&, por ejemplo

if (args!= null && args.length () > 23) {
system.out.println (args);
}


Si sabemos que args != null, el resultado del cálculo es falso y el cálculo de la expresión condicional se detiene.

No necesitamos evaluar la derecha.

Independientemente del resultado de la condición de la derecha, el valor final de la expresión booleana será falso.


Pero esto nunca ocurre en el código de producción.


Este es un error fácil de cometer, y las herramientas de análisis estático no siempre lo cometen.

Utilicé el siguiente Google Dork para ver si podía encontrar algún ejemplo público de este patrón:

Tipo de archivo: java if “!=null &”
Esta búsqueda ha encontrado código de Android en rootwindowContainer
isDocument = ¡Intención! = null & intent.isDocument ()


Este código podría pasar la revisión de código, ya que a menudo utilizamos operadores bit a bit en sentencias de asignación para enmascarar valores. Sin embargo, en este caso, el resultado es el mismo que en el ejemplo anterior con la sentencia if. Si intent siempre está vacío, se lanzará una excepción NullPointerException.

A menudo escapamos de esta estructura porque solemos realizar codificación defensiva y escribir código redundante. El cheque != null probablemente sea innecesario en la mayoría de los casos de uso.

Este es un error cometido por los programadores en el código de producción.

No sé qué tan recientes son los resultados de búsqueda, pero cuando realizo una búsqueda, los códigos que aparecen en los resultados provienen de: Google, Amazon, Apache... y yo.

Las últimas solicitudes de extracción en uno de mis proyectos de código abierto tienen como objetivo resolver este error.

if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}


¿Cómo encontrar esto?


Cuando revisé mi código de ejemplo en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.

Como Secure Code Warrior , hemos creado y revisado una Sensei bastante sencilla que permite resolver este problema.

Dado que los operadores bit a bit son totalmente eficaces y se utilizan con frecuencia en la asignación de valores, nos hemos centrado en estudiar los casos de uso de las sentencias if y el uso de Bitwise & para encontrar el código problemático.

搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”


Cuando se utiliza como expresión condicional, utiliza expresiones regulares para coincidir con «&». Por ejemplo, en la instrucción if.

Para solucionar este problema, volvemos a recurrir a las expresiones regulares. Esta vez, utilizamos la función sed de QuickFix para sustituir globalmente & por && en la expresión.

Soluciones disponibles:
-Nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
Acción:
-Reescribir:
Cambiar a: «{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}»


Nota al pie

Esto cubre el caso más común de uso indebido de los operadores bit a bit, es decir, cuando se utilizan operadores booleanos.

En otras circunstancias, como en los ejemplos de tareas, puede darse esta situación, pero al redactar las recetas debemos evitar en la medida de lo posible los falsos positivos, ya que, de lo contrario, las recetas se ignorarán o se cerrarán. Creamos recetas que se ajustan a las situaciones más habituales. A medida que Sensei evolucione, es muy probable que añadamos especificidad adicional a la función de búsqueda para abarcar más condiciones de coincidencia.

En su forma actual, la fórmula identificará muchos casos de uso prácticos y, lo que es más importante, el que se describe en mi proyecto.

Aviso: Muchos guerreros del código han contribuido a este ejemplo y a la revisión de la receta: Charlie Erikson, Matthew Carley, Robin Clairhout, Bryson Axe, Nathan Desmet y Donny Robershott. Gracias por vuestra ayuda.


---


Puedes instalar Sensei desde IntelliJ utilizando «Preferencias\ Complementos» (Mac) o «Configuración\ Complementos» (Windows). Sensei «código desensei

En el repositoriosensei de la cuenta Secure Code Warrior de Secure Code Warrior , tenemos el código fuente y las recetas de muchas de estas entradas del blog (incluida esta).

https://github.com/securecodewarrior/sensei-blog-examples

Sensei información sobre Sensei


Ver el seminario web
Empecemos.
Más información

Haga clic en el siguiente enlace y descargue el PDF de este recurso.

Secure Code Warrior puede ayudar a su organización a proteger el código a lo largo de todo el ciclo de vida del desarrollo de software y a crear una cultura que dé prioridad a la ciberseguridad. Tanto si es usted responsable de seguridad de aplicaciones, desarrollador, director de seguridad de la información o cualquier otra persona relacionada con la seguridad, podemos ayudar a su organización a reducir los riesgos asociados al código inseguro.

Ver informeReservar una demostración
Ver recursos
Compartir en:
marcas de LinkedInSocialx logotipo
¿Te interesa saber más?

Compartir en:
marcas de LinkedInSocialx logotipo
Autor
Alan Richardson
Publicado el 07 de febrero de 2021

Alan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.

Compartir en:
marcas de LinkedInSocialx logotipo

Java: Trampas - Operadores bit a bit y operadores booleanos

«Java Gotcha»: un patrón de error común que se produce fácilmente de forma inesperada.

Un problema bastante sencillo de Java que puede surgir inesperadamente es el uso de operadores bit a bit en lugar de operadores de comparación booleanos.

Por ejemplo, cuando realmente quieres escribir «&&», un simple error de entrada puede provocar que se escriba «&».

Los métodos heurísticos comunes que aprendemos al revisar el código son:

El uso de «&» o «|» en una cláusula condicional puede no ser intencionado.

En esta entrada del blog, exploraremos métodos heurísticos y determinaremos formas de identificar y corregir este problema de codificación.


¿Dónde está el problema? El uso de operaciones booleanas permite realizar operaciones bit a bit correctamente.


El uso de operadores bit a bit con valores booleanos es totalmente válido, por lo que Java no informa de ningún error sintáctico.

Si construyo una prueba JUnit para explorar la tabla de valores verdaderos de la operación bit a bit (|) y la operación bit a bit (&), veremos que la salida del operador bit a bit coincide con la tabla de valores verdaderos. Teniendo esto en cuenta, podríamos pensar que el uso del operador bit a bit no supone ningún problema.

Y tabla de verdades

Tres columnas una con a, otra con b, y la última con (a^b)


@Test
void Operador bit a bit y TruthTable () {
assertions.asserteQuals(verdadero, verdadero y verdadero);
assertions.asserteQuals(falso, verdadero y falso);
assertions.asserteQuals(falso, falso y verdadero);
assertions.asserteQuals(falso, falso y falso);
}


La prueba ha sido superada, es Java totalmente válido.


OR Tabla de verdades


Tres columnas sobre con a, una con b, y la última con (a v b)


@Test
void Operador bit a bit o tabla de valores verdaderos () {
assertions.asserteQuals(verdadero, verdadero | verdadero);
assertions.asserteQuals(verdadero, verdadero | falso);
assertions.asserteQuals(verdadero, falso | verdadero);
assertions.asserteQuals(falso, falso | falso);
}


Esta prueba también ha sido superada, ¿por qué preferimos «&&» y «||»?


La tabla de verdad es una herramienta creada para herramienta de tabla de verdad de web.standfor.edu.


Pregunta: Operación de cortocircuito


El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).

Los operadores booleanos son operadores de cortocircuito y solo se evalúan cuando es necesario.

Por ejemplo

if (args!= null & args.length () > 23) {
system.out.println (args);
}


En el código anterior, se evaluarán ambas condiciones booleanas, ya que se utiliza el operador bit a bit:

  • args!= valor vacío
  • args.length () > 23

Si args está vacío, esto expone mi código al riesgo de NullPointerException, ya que incluso si el parámetro está vacío, siempre comprobaremos args.length, ya que hay que evaluar dos condiciones booleanas.


Evaluación de cortocircuito del operador booleano


Cuando se utiliza &&, por ejemplo

if (args!= null && args.length () > 23) {
system.out.println (args);
}


Si sabemos que args != null, el resultado del cálculo es falso y el cálculo de la expresión condicional se detiene.

No necesitamos evaluar la derecha.

Independientemente del resultado de la condición de la derecha, el valor final de la expresión booleana será falso.


Pero esto nunca ocurre en el código de producción.


Este es un error fácil de cometer, y las herramientas de análisis estático no siempre lo cometen.

Utilicé el siguiente Google Dork para ver si podía encontrar algún ejemplo público de este patrón:

Tipo de archivo: java if “!=null &”
Esta búsqueda ha encontrado código de Android en rootwindowContainer
isDocument = ¡Intención! = null & intent.isDocument ()


Este código podría pasar la revisión de código, ya que a menudo utilizamos operadores bit a bit en sentencias de asignación para enmascarar valores. Sin embargo, en este caso, el resultado es el mismo que en el ejemplo anterior con la sentencia if. Si intent siempre está vacío, se lanzará una excepción NullPointerException.

A menudo escapamos de esta estructura porque solemos realizar codificación defensiva y escribir código redundante. El cheque != null probablemente sea innecesario en la mayoría de los casos de uso.

Este es un error cometido por los programadores en el código de producción.

No sé qué tan recientes son los resultados de búsqueda, pero cuando realizo una búsqueda, los códigos que aparecen en los resultados provienen de: Google, Amazon, Apache... y yo.

Las últimas solicitudes de extracción en uno de mis proyectos de código abierto tienen como objetivo resolver este error.

if (键入!=null & type.trim () .length () >0) {
AcceptMediatypeDefinitionsList.add (type.trim ());
}


¿Cómo encontrar esto?


Cuando revisé mi código de ejemplo en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.

Como Secure Code Warrior , hemos creado y revisado una Sensei bastante sencilla que permite resolver este problema.

Dado que los operadores bit a bit son totalmente eficaces y se utilizan con frecuencia en la asignación de valores, nos hemos centrado en estudiar los casos de uso de las sentencias if y el uso de Bitwise & para encontrar el código problemático.

搜索:
表情:
AnyOF:
-在:
条件:{}
价值:
区分大小写:假
匹配:“.* &。*”


Cuando se utiliza como expresión condicional, utiliza expresiones regulares para coincidir con «&». Por ejemplo, en la instrucción if.

Para solucionar este problema, volvemos a recurrir a las expresiones regulares. Esta vez, utilizamos la función sed de QuickFix para sustituir globalmente & por && en la expresión.

Soluciones disponibles:
-Nombre: «Reemplazar el operador AND bit a bit por el operador AND lógico»
Acción:
-Reescribir:
Cambiar a: «{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}»


Nota al pie

Esto cubre el caso más común de uso indebido de los operadores bit a bit, es decir, cuando se utilizan operadores booleanos.

En otras circunstancias, como en los ejemplos de tareas, puede darse esta situación, pero al redactar las recetas debemos evitar en la medida de lo posible los falsos positivos, ya que, de lo contrario, las recetas se ignorarán o se cerrarán. Creamos recetas que se ajustan a las situaciones más habituales. A medida que Sensei evolucione, es muy probable que añadamos especificidad adicional a la función de búsqueda para abarcar más condiciones de coincidencia.

En su forma actual, la fórmula identificará muchos casos de uso prácticos y, lo que es más importante, el que se describe en mi proyecto.

Aviso: Muchos guerreros del código han contribuido a este ejemplo y a la revisión de la receta: Charlie Erikson, Matthew Carley, Robin Clairhout, Bryson Axe, Nathan Desmet y Donny Robershott. Gracias por vuestra ayuda.


---


Puedes instalar Sensei desde IntelliJ utilizando «Preferencias\ Complementos» (Mac) o «Configuración\ Complementos» (Windows). Sensei «código desensei

En el repositoriosensei de la cuenta Secure Code Warrior de Secure Code Warrior , tenemos el código fuente y las recetas de muchas de estas entradas del blog (incluida esta).

https://github.com/securecodewarrior/sensei-blog-examples

Sensei información sobre Sensei


Índice

Descargar PDF
Ver recursos
¿Te interesa saber más?

Alan Richardson cuenta con más de veinte años de experiencia profesional en TI, trabajando como desarrollador y en todos los niveles de la jerarquía de pruebas, desde probador hasta jefe de pruebas. Jefe de Relaciones con los Desarrolladores en Secure Code Warrior, trabaja directamente con los equipos, para mejorar el desarrollo de un código seguro de calidad. Alan es autor de cuatro libros, entre ellos "Dear Evil Tester" y "Java For Testers". Alan también ha creado una formación en línea courses para ayudar a la gente a aprender las pruebas técnicas de la web y Selenium WebDriver con Java. Alan publica sus escritos y vídeos de formación en SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, y CompendiumDev.co.uk.

Más información

Secure Code Warrior puede ayudar a su organización a proteger el código a lo largo de todo el ciclo de vida del desarrollo de software y a crear una cultura que dé prioridad a la ciberseguridad. Tanto si es usted responsable de seguridad de aplicaciones, desarrollador, director de seguridad de la información o cualquier otra persona relacionada con la seguridad, podemos ayudar a su organización a reducir los riesgos asociados al código inseguro.

Reservar una demostraciónDescargar
Compartir en:
marcas de LinkedInSocialx logotipo
Centro de recursos

Recursos para ayudarle a empezar

Más publicaciones
Centro de recursos

Recursos para ayudarle a empezar

Más publicaciones