正则表达式背后的灾难和危机

职场   2024-09-01 08:41   浙江  

2016年,Stack Overflow遭遇了一次长达34分钟的服务中断事故。罪魁祸首是什么?是一段用来处理用户输入的代码中使用的正则表达式。

最终,确定问题耗时10分钟,编写修复方案用了14分钟,再花10分钟部署解决方案并恢复了Stack Overflow的服务。

究竟是什么导致了这次事故?

^[\s\u200c]+|[\s\u200c]+$

Stack Overflow解释道:虽然这个正则表达式看起来简单——匹配字符串末尾的所有空格——但它可能给回溯型的正则引擎带来问题。在这次事件中,有一个变态的帖子,评论行包含了大约20000个连续的空白字符。

如果字符串中包含20000个连续的空格字符,但它们不在末尾,正则引擎就会开始逐个检查每个空格。在检查完第20000个空格后,它遇到了一个不同的字符,但仍然期待一个空格或字符串的结束。

引擎开始回溯,尝试从第二个空格、第三个空格等位置开始匹配\s+$,这导致了总共199990000次的检查。这种检查次数足以造成显著的延迟。自那以后,该正则表达式已经被一个子字符串函数所替代。

什么是回溯?

当正则表达式无法匹配字符串的某一部分时,就会发生回溯。匹配过程本身是直接的,但如果正则引擎找不到匹配项,它就会开始回溯。这意味着引擎会重新审视之前的选择,并尝试不同的选项,这可能导致性能问题。

灾难性回溯

除了普通的回溯之外,还有一种特定问题称为灾难性回溯。当正则表达式引擎花费过多时间尝试不同的组合以匹配模式时,就会发生这种情况,这常常导致严重的性能下降。这种情况在复杂的正则表达式模式和大量的输入数据中尤为常见。

Stack Overflow的这次事件提醒我们,使用正则表达式时可能遇到的潜在陷阱。虽然34分钟的中断可能看起来不是大问题,但正则表达式还引发了哪些其他问题?

Cloudflare中断(2019年)

2019年7月2日,Cloudflare的一次中断是正则表达式问题导致灾难性失败的另一个典型例子。

一位工程师编写了一个容易引发严重回溯的正则表达式。这个正则表达式导致了广泛的CPU资源耗尽,使得Cloudflare的全球CPU使用率飙升至100%。

(?:(?:\"|'|\]|\}|\\|\d|(?:nan|infinity|true|false|null|undefined|symbol|math)|\`|\-|\+)+[)]*;?((?:\s|-|~|!|{}|\|\||\+)*.*(?:.*=.*)))

Cloudflare表示:“这个正则表达式的设计方式可能导致严重的回溯。正则表达式的关键部分.*(?:.*=.*).,涉及一个非捕获组,当处理某些模式时,可能导致过度的CPU使用。这种效率低下的正则表达式导致了严重的性能问题,最终导致了大规模的中断。”

CrowdStrike内核问题(2024年)

最近,CrowdStrike因为其内核驱动程序中的一个正则表达式实现不当,面临了一个重大问题,导致了广泛的系统崩溃。这一事件影响了包括企业和政府系统在内的多个领域的运营。

问题的根源在于Content Interpreter在处理基于正则表达式的Rapid Response Content时,预期的输入参数数量(21个)与实际提供的参数数量(20个)不匹配。当系统接收到带有第21个参数的输入时,Content Interpreter试图读取超出分配内存的范围,导致越界访问和随后的系统崩溃。

这一事件展示了正则表达式在关键系统中可能引起的严重问题。

我们应该放弃正则表达式吗?

我不敢说我对正则表达式了如指掌。然而,它们的问题突显了为什么我们需要谨慎使用正则表达式并探索替代解决方案。你觉得我们是时候逐步淘汰它们了吗?

END


热门推荐

当对象遇上代码:JavaScript 中的浪漫邂逅

JavaScript 性能优化全家桶:6 个方面 9 点建议

3.40秒到231.84毫秒,我的前端性能瓶颈分析全流程

2024 年前端框架大更新

前端新世界
关注前端技术,分享互联网热点
 最新文章