
Java Gotchas - Operadores bit a bit o booleanos
Java Gotchas - Operadores bit a bit o booleanos
« Java Gotcha »: un modelo de error común fácil de implementar accidentalmente.
Una trampa bastante simple en Java en la que se puede caer accidentalmente es la siguiente: utilizar un operador bit a bit en lugar de un operador de comparación booleano.
Por ejemplo, un simple error al escribir puede hacer que se escriba «&» cuando realmente se quería escribir «&&».
Una heurística habitual que aprendemos al revisar el código es la siguiente:
« & » o « | » utilizado en una instrucción condicional probablemente no esté previsto.
En este artículo del blog, exploraremos la heurística e identificaremos formas de detectar y resolver este problema de codificación.
¿Cuál es el problema? Las operaciones a nivel de bits funcionan correctamente con los booleanos.
El uso de operadores bit a bit con valores booleanos es perfectamente válido. Por lo tanto, Java no señalará ningún error de sintaxis.
Si construyo una prueba JUnit para explorar una tabla de verdad tanto para Bitwise OR (|) como para Bitwise AND (&), veremos que las salidas del operador Bitwise coinciden con la tabla de verdad. Teniendo esto en cuenta, podríamos pensar que el uso de operadores Bitwise no es un problema.
Tabla de verdad ET

@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}
La prueba ha sido satisfactoria, es Java perfectamente válido.
Tabla de verdad de OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Esta prueba también pasa, ¿por qué preferimos « &&» y « ||»?
Las imágenes de la tabla de verdad se crearon utilizando la herramienta de tabla de verdad a partir de web.standfor.edu.
Problema: Funcionamiento en cortocircuito
El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).
Un operador booleano es un operador de cortocircuito que solo evalúa lo que necesita.
p. ej.
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
En el código anterior, se evaluarán las dos condiciones booleanas, ya que se ha utilizado el operador bit a bit:
- ¡Des chiffons! = Nulo
- args.length () > 23
Esto deja mi código expuesto a una excepción NullPointerException si args es nulo, ya que siempre realizaremos la comprobación de args.length, incluso cuando args sea nulo, ya que ambas condiciones booleanas deben evaluarse.
Evaluación de cortocircuitos mediante operadores booleanos
Cuando se utiliza &&, por ejemplo
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
En cuanto lo sepamos, Args ! = null devuelve el valor False cuando se detiene la evaluación de la expresión de condición.
No necesitamos evaluar el lado derecho.
Sea cual sea el resultado de la condición del lado derecho, el valor final de la expresión booleana será falso.
Pero eso nunca ocurriría en el código de producción.
Se trata de un error bastante fácil de cometer y que no siempre es detectado por las herramientas de análisis estático.
He utilizado el siguiente Google Dork para ver si podía encontrar ejemplos públicos de este modelo:
tipo de archivo: java si «! =nul &»
Esta búsqueda permitió recuperar código de Android en RootWindowContainer
IsDocument = intention ! = null e Intent.isDocument ()
Este es el tipo de código que puede pasar una revisión de código, ya que a menudo utilizamos operadores bit a bit en las instrucciones de asignación para ocultar los valores. Pero en este caso, el resultado es el mismo que en el ejemplo de instrucción if anterior. Si la intención es nula, se lanzará una excepción NullPointerException.
Muy a menudo, nos salimos con la nuestra con esta construcción porque solemos programar de forma defensiva y escribimos código redundante. La comprobación de ! = null puede ser redundante en la mayoría de los casos de uso.
Se trata de un error cometido por los programadores en el código de producción.
No sé si los resultados de la búsqueda están actualizados, pero cuando la ejecuté, se mostraron resultados que contenían código procedente de: Google, Amazon, Apache... y yo.
Una reciente solicitud de extracción en uno de mis proyectos de código abierto consistía precisamente en corregir este error.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
¿Cómo encontrarlo?
Cuando comprobé mi ejemplo de código en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.
Como equipo de Secure Code Warrior, hemos creado y revisado una receta Sensei sencilla que podría dar respuesta a este problema.
Dado que los operadores bit a bit son perfectamente válidos y se utilizan a menudo en las asignaciones, nos hemos centrado en el caso de uso de las instrucciones if y en el uso de Bitwise & para encontrar el código problemático.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Utiliza una expresión regular para coincidir con «&» cuando se utiliza como expresión de condición, por ejemplo, en una instrucción if.
Para resolver este problema, volvimos a recurrir a las expresiones regulares. Esta vez, utilice la función sed de QuickFix para sustituir globalmente el & de la expresión por &&.
Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »
Notas finales
Esto cubre el uso indebido más común de un operador bit a bit, es decir, cuando realmente se esperaba un operador booleano.
En otras situaciones, esto puede ocurrir, por ejemplo, en el caso de la asignación, pero al redactar las recetas, debemos intentar evitar una identificación falsamente positiva, ya que, de lo contrario, las recetas se ignorarán o desactivarán. Elaboramos recetas que se corresponden con los eventos más habituales. A medida que Sensei evolucione, podríamos añadir una especificidad adicional a la función de búsqueda para cubrir más condiciones correspondientes.
En su forma actual, esta receta permitiría identificar numerosos casos de uso actuales y, lo que es más importante, el que se ha señalado en mi proyecto.
NOTA: Numerosos expertos en código han contribuido a este ejemplo y a esta crítica de receta: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Gracias por tu ayuda.
---
Puede instalar Sensei IntelliJ utilizando «Preferencias \ Complementos» (Mac) o «Configuración \ Complementos» (Windows) y, a continuación, simplemente busqueSensei Code».
Tenemos mucho código fuente y recetas para estos artículos de blog (incluido este) en el repositoriosensei de la cuenta GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
En este artículo del blog, analizamos un error común en la codificación Java (el uso de un operador a nivel de bit en lugar de un operador condicional), el error al que expone nuestro código y cómo podemos utilizar Sensei corregir y detectar el problema.
Alan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Secure Code Warrior aquí para ayudar a su organización a proteger el código a lo largo de todo el ciclo de desarrollo de software y a crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es responsable de la seguridad de las aplicaciones, desarrollador, responsable de la seguridad informática o cualquier otra persona involucrada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código no seguro.
Reserve una demostraciónAlan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.
Java Gotchas - Operadores bit a bit o booleanos
« Java Gotcha »: un modelo de error común fácil de implementar accidentalmente.
Una trampa bastante simple en Java en la que se puede caer accidentalmente es la siguiente: utilizar un operador bit a bit en lugar de un operador de comparación booleano.
Por ejemplo, un simple error al escribir puede hacer que se escriba «&» cuando realmente se quería escribir «&&».
Una heurística habitual que aprendemos al revisar el código es la siguiente:
« & » o « | » utilizado en una instrucción condicional probablemente no esté previsto.
En este artículo del blog, exploraremos la heurística e identificaremos formas de detectar y resolver este problema de codificación.
¿Cuál es el problema? Las operaciones a nivel de bits funcionan correctamente con los booleanos.
El uso de operadores bit a bit con valores booleanos es perfectamente válido. Por lo tanto, Java no señalará ningún error de sintaxis.
Si construyo una prueba JUnit para explorar una tabla de verdad tanto para Bitwise OR (|) como para Bitwise AND (&), veremos que las salidas del operador Bitwise coinciden con la tabla de verdad. Teniendo esto en cuenta, podríamos pensar que el uso de operadores Bitwise no es un problema.
Tabla de verdad ET

@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}
La prueba ha sido satisfactoria, es Java perfectamente válido.
Tabla de verdad de OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Esta prueba también pasa, ¿por qué preferimos « &&» y « ||»?
Las imágenes de la tabla de verdad se crearon utilizando la herramienta de tabla de verdad a partir de web.standfor.edu.
Problema: Funcionamiento en cortocircuito
El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).
Un operador booleano es un operador de cortocircuito que solo evalúa lo que necesita.
p. ej.
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
En el código anterior, se evaluarán las dos condiciones booleanas, ya que se ha utilizado el operador bit a bit:
- ¡Des chiffons! = Nulo
- args.length () > 23
Esto deja mi código expuesto a una excepción NullPointerException si args es nulo, ya que siempre realizaremos la comprobación de args.length, incluso cuando args sea nulo, ya que ambas condiciones booleanas deben evaluarse.
Evaluación de cortocircuitos mediante operadores booleanos
Cuando se utiliza &&, por ejemplo
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
En cuanto lo sepamos, Args ! = null devuelve el valor False cuando se detiene la evaluación de la expresión de condición.
No necesitamos evaluar el lado derecho.
Sea cual sea el resultado de la condición del lado derecho, el valor final de la expresión booleana será falso.
Pero eso nunca ocurriría en el código de producción.
Se trata de un error bastante fácil de cometer y que no siempre es detectado por las herramientas de análisis estático.
He utilizado el siguiente Google Dork para ver si podía encontrar ejemplos públicos de este modelo:
tipo de archivo: java si «! =nul &»
Esta búsqueda permitió recuperar código de Android en RootWindowContainer
IsDocument = intention ! = null e Intent.isDocument ()
Este es el tipo de código que puede pasar una revisión de código, ya que a menudo utilizamos operadores bit a bit en las instrucciones de asignación para ocultar los valores. Pero en este caso, el resultado es el mismo que en el ejemplo de instrucción if anterior. Si la intención es nula, se lanzará una excepción NullPointerException.
Muy a menudo, nos salimos con la nuestra con esta construcción porque solemos programar de forma defensiva y escribimos código redundante. La comprobación de ! = null puede ser redundante en la mayoría de los casos de uso.
Se trata de un error cometido por los programadores en el código de producción.
No sé si los resultados de la búsqueda están actualizados, pero cuando la ejecuté, se mostraron resultados que contenían código procedente de: Google, Amazon, Apache... y yo.
Una reciente solicitud de extracción en uno de mis proyectos de código abierto consistía precisamente en corregir este error.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
¿Cómo encontrarlo?
Cuando comprobé mi ejemplo de código en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.
Como equipo de Secure Code Warrior, hemos creado y revisado una receta Sensei sencilla que podría dar respuesta a este problema.
Dado que los operadores bit a bit son perfectamente válidos y se utilizan a menudo en las asignaciones, nos hemos centrado en el caso de uso de las instrucciones if y en el uso de Bitwise & para encontrar el código problemático.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Utiliza una expresión regular para coincidir con «&» cuando se utiliza como expresión de condición, por ejemplo, en una instrucción if.
Para resolver este problema, volvimos a recurrir a las expresiones regulares. Esta vez, utilice la función sed de QuickFix para sustituir globalmente el & de la expresión por &&.
Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »
Notas finales
Esto cubre el uso indebido más común de un operador bit a bit, es decir, cuando realmente se esperaba un operador booleano.
En otras situaciones, esto puede ocurrir, por ejemplo, en el caso de la asignación, pero al redactar las recetas, debemos intentar evitar una identificación falsamente positiva, ya que, de lo contrario, las recetas se ignorarán o desactivarán. Elaboramos recetas que se corresponden con los eventos más habituales. A medida que Sensei evolucione, podríamos añadir una especificidad adicional a la función de búsqueda para cubrir más condiciones correspondientes.
En su forma actual, esta receta permitiría identificar numerosos casos de uso actuales y, lo que es más importante, el que se ha señalado en mi proyecto.
NOTA: Numerosos expertos en código han contribuido a este ejemplo y a esta crítica de receta: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Gracias por tu ayuda.
---
Puede instalar Sensei IntelliJ utilizando «Preferencias \ Complementos» (Mac) o «Configuración \ Complementos» (Windows) y, a continuación, simplemente busqueSensei Code».
Tenemos mucho código fuente y recetas para estos artículos de blog (incluido este) en el repositoriosensei de la cuenta GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
Java Gotchas - Operadores bit a bit o booleanos
« Java Gotcha »: un modelo de error común fácil de implementar accidentalmente.
Una trampa bastante simple en Java en la que se puede caer accidentalmente es la siguiente: utilizar un operador bit a bit en lugar de un operador de comparación booleano.
Por ejemplo, un simple error al escribir puede hacer que se escriba «&» cuando realmente se quería escribir «&&».
Una heurística habitual que aprendemos al revisar el código es la siguiente:
« & » o « | » utilizado en una instrucción condicional probablemente no esté previsto.
En este artículo del blog, exploraremos la heurística e identificaremos formas de detectar y resolver este problema de codificación.
¿Cuál es el problema? Las operaciones a nivel de bits funcionan correctamente con los booleanos.
El uso de operadores bit a bit con valores booleanos es perfectamente válido. Por lo tanto, Java no señalará ningún error de sintaxis.
Si construyo una prueba JUnit para explorar una tabla de verdad tanto para Bitwise OR (|) como para Bitwise AND (&), veremos que las salidas del operador Bitwise coinciden con la tabla de verdad. Teniendo esto en cuenta, podríamos pensar que el uso de operadores Bitwise no es un problema.
Tabla de verdad ET

@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}
La prueba ha sido satisfactoria, es Java perfectamente válido.
Tabla de verdad de OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Esta prueba también pasa, ¿por qué preferimos « &&» y « ||»?
Las imágenes de la tabla de verdad se crearon utilizando la herramienta de tabla de verdad a partir de web.standfor.edu.
Problema: Funcionamiento en cortocircuito
El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).
Un operador booleano es un operador de cortocircuito que solo evalúa lo que necesita.
p. ej.
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
En el código anterior, se evaluarán las dos condiciones booleanas, ya que se ha utilizado el operador bit a bit:
- ¡Des chiffons! = Nulo
- args.length () > 23
Esto deja mi código expuesto a una excepción NullPointerException si args es nulo, ya que siempre realizaremos la comprobación de args.length, incluso cuando args sea nulo, ya que ambas condiciones booleanas deben evaluarse.
Evaluación de cortocircuitos mediante operadores booleanos
Cuando se utiliza &&, por ejemplo
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
En cuanto lo sepamos, Args ! = null devuelve el valor False cuando se detiene la evaluación de la expresión de condición.
No necesitamos evaluar el lado derecho.
Sea cual sea el resultado de la condición del lado derecho, el valor final de la expresión booleana será falso.
Pero eso nunca ocurriría en el código de producción.
Se trata de un error bastante fácil de cometer y que no siempre es detectado por las herramientas de análisis estático.
He utilizado el siguiente Google Dork para ver si podía encontrar ejemplos públicos de este modelo:
tipo de archivo: java si «! =nul &»
Esta búsqueda permitió recuperar código de Android en RootWindowContainer
IsDocument = intention ! = null e Intent.isDocument ()
Este es el tipo de código que puede pasar una revisión de código, ya que a menudo utilizamos operadores bit a bit en las instrucciones de asignación para ocultar los valores. Pero en este caso, el resultado es el mismo que en el ejemplo de instrucción if anterior. Si la intención es nula, se lanzará una excepción NullPointerException.
Muy a menudo, nos salimos con la nuestra con esta construcción porque solemos programar de forma defensiva y escribimos código redundante. La comprobación de ! = null puede ser redundante en la mayoría de los casos de uso.
Se trata de un error cometido por los programadores en el código de producción.
No sé si los resultados de la búsqueda están actualizados, pero cuando la ejecuté, se mostraron resultados que contenían código procedente de: Google, Amazon, Apache... y yo.
Una reciente solicitud de extracción en uno de mis proyectos de código abierto consistía precisamente en corregir este error.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
¿Cómo encontrarlo?
Cuando comprobé mi ejemplo de código en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.
Como equipo de Secure Code Warrior, hemos creado y revisado una receta Sensei sencilla que podría dar respuesta a este problema.
Dado que los operadores bit a bit son perfectamente válidos y se utilizan a menudo en las asignaciones, nos hemos centrado en el caso de uso de las instrucciones if y en el uso de Bitwise & para encontrar el código problemático.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Utiliza una expresión regular para coincidir con «&» cuando se utiliza como expresión de condición, por ejemplo, en una instrucción if.
Para resolver este problema, volvimos a recurrir a las expresiones regulares. Esta vez, utilice la función sed de QuickFix para sustituir globalmente el & de la expresión por &&.
Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »
Notas finales
Esto cubre el uso indebido más común de un operador bit a bit, es decir, cuando realmente se esperaba un operador booleano.
En otras situaciones, esto puede ocurrir, por ejemplo, en el caso de la asignación, pero al redactar las recetas, debemos intentar evitar una identificación falsamente positiva, ya que, de lo contrario, las recetas se ignorarán o desactivarán. Elaboramos recetas que se corresponden con los eventos más habituales. A medida que Sensei evolucione, podríamos añadir una especificidad adicional a la función de búsqueda para cubrir más condiciones correspondientes.
En su forma actual, esta receta permitiría identificar numerosos casos de uso actuales y, lo que es más importante, el que se ha señalado en mi proyecto.
NOTA: Numerosos expertos en código han contribuido a este ejemplo y a esta crítica de receta: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Gracias por tu ayuda.
---
Puede instalar Sensei IntelliJ utilizando «Preferencias \ Complementos» (Mac) o «Configuración \ Complementos» (Windows) y, a continuación, simplemente busqueSensei Code».
Tenemos mucho código fuente y recetas para estos artículos de blog (incluido este) en el repositoriosensei de la cuenta GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples

Haga clic en el enlace siguiente y descargue el PDF de este recurso.
Secure Code Warrior aquí para ayudar a su organización a proteger el código a lo largo de todo el ciclo de desarrollo de software y a crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es responsable de la seguridad de las aplicaciones, desarrollador, responsable de la seguridad informática o cualquier otra persona involucrada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código no seguro.
Mostrar el informeReserve una demostraciónAlan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.
Java Gotchas - Operadores bit a bit o booleanos
« Java Gotcha »: un modelo de error común fácil de implementar accidentalmente.
Una trampa bastante simple en Java en la que se puede caer accidentalmente es la siguiente: utilizar un operador bit a bit en lugar de un operador de comparación booleano.
Por ejemplo, un simple error al escribir puede hacer que se escriba «&» cuando realmente se quería escribir «&&».
Una heurística habitual que aprendemos al revisar el código es la siguiente:
« & » o « | » utilizado en una instrucción condicional probablemente no esté previsto.
En este artículo del blog, exploraremos la heurística e identificaremos formas de detectar y resolver este problema de codificación.
¿Cuál es el problema? Las operaciones a nivel de bits funcionan correctamente con los booleanos.
El uso de operadores bit a bit con valores booleanos es perfectamente válido. Por lo tanto, Java no señalará ningún error de sintaxis.
Si construyo una prueba JUnit para explorar una tabla de verdad tanto para Bitwise OR (|) como para Bitwise AND (&), veremos que las salidas del operador Bitwise coinciden con la tabla de verdad. Teniendo esto en cuenta, podríamos pensar que el uso de operadores Bitwise no es un problema.
Tabla de verdad ET

@Test
annulez BitwiseOperatorsAndTruthTable () {
assertions.assertEquals (vrai, vrai et vrai) ;
Assertions.assertEquals (faux, vrai et faux) ;
Assertions.assertEquals (faux, faux et vrai) ;
Assertions.assertEquals (faux, faux et faux) ;
}
La prueba ha sido satisfactoria, es Java perfectamente válido.
Tabla de verdad de OR

@Test
annulez BitwiseOperatorsorTruthTable () {
assertions.assertEquals (vrai, vrai | vrai) ;
Assertions.assertEquals (vrai, vrai | faux) ;
Assertions.assertEquals (vrai, faux | vrai) ;
Assertions.assertEquals (faux, faux | faux) ;
}
Esta prueba también pasa, ¿por qué preferimos « &&» y « ||»?
Las imágenes de la tabla de verdad se crearon utilizando la herramienta de tabla de verdad a partir de web.standfor.edu.
Problema: Funcionamiento en cortocircuito
El verdadero problema es la diferencia de comportamiento entre los operadores bit a bit (&, |) y los operadores booleanos (&&, ||).
Un operador booleano es un operador de cortocircuito que solo evalúa lo que necesita.
p. ej.
si (args) ! = null et args.length () > 23) {
System.out.println (args) ;
}
En el código anterior, se evaluarán las dos condiciones booleanas, ya que se ha utilizado el operador bit a bit:
- ¡Des chiffons! = Nulo
- args.length () > 23
Esto deja mi código expuesto a una excepción NullPointerException si args es nulo, ya que siempre realizaremos la comprobación de args.length, incluso cuando args sea nulo, ya que ambas condiciones booleanas deben evaluarse.
Evaluación de cortocircuitos mediante operadores booleanos
Cuando se utiliza &&, por ejemplo
si (args) ! = null && args.length () > 23) {
System.out.println (args) ;
}
En cuanto lo sepamos, Args ! = null devuelve el valor False cuando se detiene la evaluación de la expresión de condición.
No necesitamos evaluar el lado derecho.
Sea cual sea el resultado de la condición del lado derecho, el valor final de la expresión booleana será falso.
Pero eso nunca ocurriría en el código de producción.
Se trata de un error bastante fácil de cometer y que no siempre es detectado por las herramientas de análisis estático.
He utilizado el siguiente Google Dork para ver si podía encontrar ejemplos públicos de este modelo:
tipo de archivo: java si «! =nul &»
Esta búsqueda permitió recuperar código de Android en RootWindowContainer
IsDocument = intention ! = null e Intent.isDocument ()
Este es el tipo de código que puede pasar una revisión de código, ya que a menudo utilizamos operadores bit a bit en las instrucciones de asignación para ocultar los valores. Pero en este caso, el resultado es el mismo que en el ejemplo de instrucción if anterior. Si la intención es nula, se lanzará una excepción NullPointerException.
Muy a menudo, nos salimos con la nuestra con esta construcción porque solemos programar de forma defensiva y escribimos código redundante. La comprobación de ! = null puede ser redundante en la mayoría de los casos de uso.
Se trata de un error cometido por los programadores en el código de producción.
No sé si los resultados de la búsqueda están actualizados, pero cuando la ejecuté, se mostraron resultados que contenían código procedente de: Google, Amazon, Apache... y yo.
Una reciente solicitud de extracción en uno de mis proyectos de código abierto consistía precisamente en corregir este error.
si (tapez ! =null et tapez .trim () .length () >0) {
AcceptMediaTypeDefinitionsList.add (type.trim ()) ;
}
¿Cómo encontrarlo?
Cuando comprobé mi ejemplo de código en varios analizadores estáticos, ninguno de ellos detectó este código de autodestrucción oculto.
Como equipo de Secure Code Warrior, hemos creado y revisado una receta Sensei sencilla que podría dar respuesta a este problema.
Dado que los operadores bit a bit son perfectamente válidos y se utilizan a menudo en las asignaciones, nos hemos centrado en el caso de uso de las instrucciones if y en el uso de Bitwise & para encontrar el código problemático.
recherche :
expression :
N'importe lequel des :
- dans :
état : {}
valeur :
CaseSensitive : faux
correspond à : « .* » et . * »
Utiliza una expresión regular para coincidir con «&» cuando se utiliza como expresión de condición, por ejemplo, en una instrucción if.
Para resolver este problema, volvimos a recurrir a las expresiones regulares. Esta vez, utilice la función sed de QuickFix para sustituir globalmente el & de la expresión por &&.
Correctifs disponibles :
- nom : « Remplacer l'opérateur AND au niveau du bit par l'opérateur ET logique »
actions :
- réécrire :
à : « {{#sed}} s/&/&&/g, {{{.}}} {{/sed}} »
Notas finales
Esto cubre el uso indebido más común de un operador bit a bit, es decir, cuando realmente se esperaba un operador booleano.
En otras situaciones, esto puede ocurrir, por ejemplo, en el caso de la asignación, pero al redactar las recetas, debemos intentar evitar una identificación falsamente positiva, ya que, de lo contrario, las recetas se ignorarán o desactivarán. Elaboramos recetas que se corresponden con los eventos más habituales. A medida que Sensei evolucione, podríamos añadir una especificidad adicional a la función de búsqueda para cubrir más condiciones correspondientes.
En su forma actual, esta receta permitiría identificar numerosos casos de uso actuales y, lo que es más importante, el que se ha señalado en mi proyecto.
NOTA: Numerosos expertos en código han contribuido a este ejemplo y a esta crítica de receta: Charlie Eriksen, Matthieu Calie, Robin Claerhaut, Brysen Ackx, Nathan Desmet, Downey Robersscheuten. Gracias por tu ayuda.
---
Puede instalar Sensei IntelliJ utilizando «Preferencias \ Complementos» (Mac) o «Configuración \ Complementos» (Windows) y, a continuación, simplemente busqueSensei Code».
Tenemos mucho código fuente y recetas para estos artículos de blog (incluido este) en el repositoriosensei de la cuenta GitHub de Secure Code Warrior.
https://github.com/securecodewarrior/sensei-blog-examples
Índice
Alan Richardson possède plus de vingt ans d'expérience professionnelle en informatique. Il a travaillé en tant que développeur et a occupé tous les niveaux de la hiérarchie des tests, du testeur au responsable des tests. Responsable des relations avec les développeurs chez Secure Code Warrior, il travaille directement avec les équipes, pour améliorer le développement d'un code sécurisé de qualité. Alan est l'auteur de quatre livres, dont « Dear Evil Tester » et « Java For Testers ». Alan a également créé des cours de formation en ligne pour aider les utilisateurs à apprendre les tests techniques sur le Web et Selenium WebDriver avec Java. Alan publie ses vidéos d'écriture et de formation sur SeleniumSimplified.com, EvilTester.com, JavaForTesters.com et CompendiumDev.co.uk.

Secure Code Warrior aquí para ayudar a su organización a proteger el código a lo largo de todo el ciclo de desarrollo de software y a crear una cultura en la que la ciberseguridad sea una prioridad. Tanto si es responsable de la seguridad de las aplicaciones, desarrollador, responsable de la seguridad informática o cualquier otra persona involucrada en la seguridad, podemos ayudar a su organización a reducir los riesgos asociados a un código no seguro.
Reserve una demostraciónDescargarRecursos para ayudarle a empezar
Temas y contenidos de formación sobre el código seguro
Nuestro contenido de vanguardia evoluciona constantemente para adaptarse al panorama en constante cambio del desarrollo de software, teniendo en cuenta su función. Temas que abarcan desde la IA hasta la inyección de XQuery, ofrecidos para una variedad de puestos, desde arquitectos hasta ingenieros, pasando por jefes de producto y control de calidad. Descubra una visión general de lo que nuestro catálogo de contenidos tiene para ofrecer por tema y por función.
La Cámara de Comercio establece el estándar para la seguridad impulsada por desarrolladores a gran escala
Kamer van Koophandel comparte cómo ha integrado la codificación segura en el desarrollo diario mediante certificaciones basadas en roles, evaluaciones comparativas de Trust Score y una cultura de responsabilidad compartida en materia de seguridad.
Modelado de amenazas con IA: convertir a cada desarrollador en un modelador de amenazas
Saldrá mejor equipado para ayudar a los desarrolladores a combinar ideas y técnicas de modelado de amenazas con las herramientas de IA que ya utilizan para reforzar la seguridad, mejorar la colaboración y crear software más resistente desde el principio.
Recursos para ayudarle a empezar
Cybermon está de vuelta: las missions Beat the Boss ya están disponibles bajo demanda.
Cybermon 2025 Beat the Boss ya está disponible todo el año en SCW. Implemente desafíos de seguridad avanzados relacionados con la IA y el LLM para reforzar el desarrollo seguro de la IA a gran escala.
Explicación de la ley sobre ciberresiliencia: lo que significa para el desarrollo de software seguro desde el diseño.
Descubra qué exige la ley europea sobre ciberresiliencia (CRA), a quién se aplica y cómo los equipos de ingenieros pueden prepararse mediante prácticas de seguridad desde el diseño, la prevención de vulnerabilidades y el refuerzo de las capacidades de los desarrolladores.
Facilitador 1: Criterios de éxito definidos y medibles
El facilitador 1 da inicio a nuestra serie de 10 partes titulada «Facilitadores del éxito», mostrando cómo combinar la codificación segura con resultados comerciales, como la reducción de riesgos y la rapidez, para garantizar la madurez a largo plazo de los programas.




%20(1).avif)
.avif)
