Blog

Java 陷阱-按位运算符与布尔运算符

February 7, 2021
Alan Richardson

Java 陷阱-按位运算符与布尔运算符

> “Java Gotcha”-一种很容易意外实现的常见错误模式。

意外掉入的一个相当简单的 Java 问题是:使用按位运算符而不是布尔比较运算符。

例如,当你真正想写 “&&” 时,一个简单的输入错误可能会导致写入 “&”。

我们在审查代码时学到的常见启发式方法是:

> 在条件语句中使用 “&” 或 “|” 可能不是故意的。

在这篇博客文章中,我们将探讨启发式方法,并确定识别和修复此编码问题的方法。


问题出在哪里?使用布尔运算可以正常进行按位运算


使用带布尔值的按位运算符是完全有效的,因此 Java 不会报告语法错误。

如果我构造一个 JUnit 测试来探索按位或(|)和按位与(&)的真值表,那么我们将看到按位运算符的输出与真值表相匹配。鉴于此,我们可能会认为使用 Bitwise 运算符不是问题。

AND 真相表

Three columns on with a, one with b, and the last with (a^b)


@Test
void 按位运算符和 TruthTable () {
assertions.asserteQuals(真、真和真);
assertions.asserteQuals(假、对和错);
assertions.asserteQuals(假、假和真);
assertions.asserteQuals(假、假和假);
}


测试通过了,这是完全有效的 Java。


OR 真相表


Three columns on with a, one with b, and the last with (a v b)


@Test
void 按位运算符或真值表 () {
assertions.asserteQuals(真,真 | 真);
assertions.asserteQuals(真,真 | 假);
assertions.asserteQuals(真,假 | 真);
assertions.asserteQuals(假,假 | 假);
}


这个测试也通过了,为什么我们更喜欢 “&&' 和 “||'?


真相表图像是使用创建的 真相表工具web.standfor.edu


问题:短路操作


真正的问题是按位(&,|)和布尔运算符(&&,||)之间的行为差异。

布尔运算符是短路运算符,只能根据需要进行评估。

例如

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


在上面的代码中,两个布尔条件都将求值,因为使用了 Bitwise 运算符:

  • args!= 空值
  • args.length () > 23

如果args为空,这会使我的代码面临NullPointerException的风险,因为即使参数为空,我们也将始终对args.length进行检查,因为必须评估两个布尔条件。


布尔运算符短路评估


当使用 && 时,例如

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


只要我们知道那个 args!= null 计算结果为 false 条件表达式计算停止。

我们不需要评估右边。

无论右边条件的结果如何,布尔表达式的最终值都将是假的。


但这在生产代码中永远不会发生


这是一个很容易犯的错误,静态分析工具并不总是会犯这个错误。

我使用了以下 Google Dork 来查看能否找到这种模式的任何公开示例:

文件类型:java if “!=null &”
这次搜索在 rootwindowContainer 中找回了一些来自 Android 的代码
isDocument = 意图!= null & intent.isDocument ()


这种代码可能会通过代码审查,因为我们经常在赋值语句中使用 Bitwise 运算符来掩盖值。但是在这种情况下,结果与上面的 if 语句示例相同。如果 intent 永远为空,则会抛出 NullPointerException。

我们经常逃脱这种结构,因为我们经常进行防御性编码并编写冗余代码。支票!= null 在大多数用例中很可能是多余的。

这是程序员在生产代码中犯的错误。

我不知道搜索结果有多新,但是当我进行搜索时,结果返回的代码来自:谷歌、亚马逊、Apache... 还有我。

最近的 拉取请求 在我的一个开源项目中,正是为了解决这个错误。

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


如何找到这个


当我在几个静态分析器中查看我的示例代码时,他们都没有发现这个隐藏的自毁代码。

作为 Secure Code Warrior 的一个团队,我们创建并审查了一个相当简单的 Sensei 配方,可以借此解决这个问题。

由于按位运算符是完全有效的,并且经常用于赋值,因此我们重点研究了 if 语句的用例以及 Bitwise & 的使用,以找到有问题的代码。

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


当它用作条件表达式时,它使用正则表达式来匹配 “&”。例如在 if 语句中。

为了修复这个问题,我们再次依赖正则表达式。这次使用 QuickFix 中的 sed 函数将表达式中的 & 全局替换为 &&。

可用修复程序:
-名称:“将按位 AND 运算符替换为逻辑 AND 运算符”
行动:
-重写:
改为:“{{#sed}} s/&/&&&g,{{{.}}} {{/sed}}”


尾注

这涵盖了最常见的按位运算符滥用情况,即实际使用布尔运算符时。

在其他情况下可能会出现这种情况,例如任务示例,但是在编写食谱时,我们必须尽量避免假阳性识别,否则食谱将被忽略或关闭。我们创建配方以匹配最常见的情况。随着Sensei的发展,我们很可能会在搜索功能中增加额外的特异性,以涵盖更多的匹配条件。

按照目前的形式,该配方将识别许多实际用例,并且 最重要的是,我的项目中报道的那个。

注意:有不少代码勇士为这个例子和食谱审查做出了贡献——查理·埃里克森、马修·卡莉、罗宾·克莱尔豪特、布莱森·阿克斯、内森·德斯梅特、唐尼·罗伯舒顿。谢谢你的帮助。


---


你可以使用 “首选项\ 插件” (Mac) 或 “设置\ 插件” (Windows) 从 IntelliJ 中安装 Sensei 然后只需搜索 “sensei 安全代码”

在 Secure Code Warrior GitHub 账户的 “sensei-blog-examples” 存储库中,我们有许多这些博客文章(包括这篇文章)的源代码和食谱。

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

了解有关 Sensei 的更多信息


标语

Govern AI-driven development before it ships

Measure AI-assisted risk, enforce secure coding policy at commit, and accelerate secure delivery across your SDLC.

book a demo
标语

Explore more blogs

Lorem Issum diam quis eim leboutis ein selerisque lobortis sepitis beelrisque lobortis sepitis celerisque lobortis celeriskue filmentis celeriskue filmentis celeriskue diam

browse all
Case Study
Filter Label
This is some text inside of a div block.

Supercharged Security Awareness: How Tournaments are Inspiring Developers at Erste Group

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

Learn More
Case Study
Filter Label
This is some text inside of a div block.

Security as culture: How Blue Prism cultivates world-class secure developers

Learn how Blue Prism, the global leader in intelligent automation for the enterprise, used Secure Code Warrior's agile learning platform to create a security-first culture with their developers, achieve their business goals, and ship secure code at speed

Learn More
Case Study
Filter Label
This is some text inside of a div block.

One Culture of Security: How Sage built their security champions program with agile secure code learning

Discover how Sage enhanced security with a flexible, relationship-focused approach, creating 200+ security champions and achieving measurable risk reduction.

Learn More
Blog
Filter Label
This is some text inside of a div block.

Enabler 7: Developer Recognition

Recognition fuels participation. Enabler 7 celebrates developer achievement loudly, with rewards and exclusive swag that mark real, earned secure coding wins.

Learn More
Blog
Filter Label
This is some text inside of a div block.

Named in the Gartner® Hype Cycle™ for Application Security 2026

Secure Code Warrior is named in the Gartner® Hype Cycle™ for Application Security, 2026 for Agentic Coding Security and Secure Coding Training. Here's why.

Learn More
Blog
Filter Label
This is some text inside of a div block.

Are you a CISO or Engineering Leader worried about the Security and Cost of LLM code generation?

Review the SCW AI Trust Index, our proprietary LLM benchmarking data, before going all-in on an AI model.

Learn More

Secure AI-driven development before it ships

See developer risk, enforce policy, and prevent vulnerabilities across your software development lifecycle.

预约演示
No items found.