【问题标题】:Limit a variety of regex patterns to execute by user on the server限制用户在服务器上执行的各种正则表达式模式
【发布时间】:2015-11-26 20:39:14
【问题描述】:

我让用户可以在我的 Java 服务器上对大量文本执行正则表达式。它是用PatternMatcher Java 类实现的。

在某些情况下,它会导致StackOverflowError。它发生在复杂的正则表达式和/或发生大量匹配时。

Pattern pattern = Pattern.compile(term);
Matcher matcher = pattern.matcher(text);


    java.lang.StackOverflowError: null
        at java.util.regex.Pattern$Branch.match(Pattern.java:4604) ~[na:1.8.0_45-internal]
        at java.util.regex.Pattern$GroupHead.match(Pattern.java:4658) ~[na:1.8.0_45-internal]
...

问题是如何限制用户只使用正则表达式的一小部分,以避免此类错误和不必要的高服务器 CPU 使用率。可以用纯 Java 或任何第三方 Java 库来完成吗?

或者也许还有其他可能的解决方案,即只是 try/catch StackOverflowError

【问题讨论】:

  • 除了建议的其他选项之外,还有一个简单的缓存层。不是为了结果,而是为了导致 StackOverflow 的正则表达式和正在编写这些正则表达式的用户。 ConcurrentHashMap 包含 Regex 作为键和 userId 作为值应该足够了。然后如果可能的话,与用户交谈并告诉他们不要运行这些正则表达式。否则,至少在再次运行正则表达式并等待 StackOverflow 之前检查 Map。可以帮助减轻 CPU 负载。

标签: java regex


【解决方案1】:

Try/catch StackOverflowError,再加上一个激进的超时时间(比如 1 秒),几乎可以肯定是你最好的选择。这也是迄今为止最简单的选择。在开发实现时,您可能还需要catch 其他异常类型。

请注意,要使超时起作用,您需要使用an interruptible CharSequence implementation 而不是普通的String。我之前已经成功地将这种策略与编写不佳、正则表达式繁重的第三方库一起使用。

上面链接的问答应该可以帮助您入门:Cancelling a long running regex match?


您建议的原始方法——尝试预先检测“不良”模式——确实是一个非常难以解决的问题。你熟悉the halting problem吗?它只比解决这个问题(一般情况下是impossible to solve)简单一点。

【讨论】:

  • 谢谢,马特。我可能会停止尝试/捕获方法。但是当许多用户同时执行复杂的正则表达式时,它并不能保护服务器免受可能的高 CPU 使用率。我怀疑的另一件事是不建议抓住Error
  • 让用户在你的服务器上运行正则表达式也会导致糟糕的用户体验。没有人会立即获得正则表达式,并且需要数年时间才能掌握它们。帮大家一个忙,并实施针对手头工作量身定制的自定义搜索工具。
猜你喜欢
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多