3

我已经在这里得到了一些帮助,但我遇到了一个稍微不同的问题。我正在寻找DocumentBuilderFactory创建 a 但没有限制ExpandEntityReferences. 我有以下正则表达式:

(?x)

# finds DocumentBuilderFactory creation and pulls out the variable name
# of the form DocumentBuilderFactory VARNAME = DocumentBuilderFactory.newInstance
# then checks if that variable name has one of three acceptable ways to stop XXE attacks
# matches any instance where the variable is initialized, but not restricted

(?:
   # This is for DocumentBuilderFactory VARNAME = DocumentBuilderFactory.newInstance with many possible alternates
   DocumentBuilderFactory
   [\s]+?
   (\w+)
   [\s]*?
   =
   [\s]*?
   (?:.*?DocumentBuilderFactory)
   [.\s]+
   newInstance.*

   # checks that the var name is NOT (using ?!) using one of the acceptable rejection methods
   (?!\1[.\s]+
      (?:setFeature\s*\(\s*"http://xml.org/sax/features/external-general-entities"\s*,\s*false\s*\)
        |setFeature\s*\(\s*"http://apache.org/xml/features/disallow-doctype-decl"\s*,\s*false\s*\)
        |setExpandEntityReferences\s*\(\s*false\s*\))
   )
)

测试文件可能如下所示:

// Set the parser properties
  javax.xml.parsers.DocumentBuilderFactory factory = 
    javax.xml.parsers.DocumentBuilderFactory.newInstance();
  factory.setNamespaceAware(true);
  factory.setValidating(false);
  factory.setExpandEntityReferences(false);
  factory.setIgnoringComments(true);
  factory.setIgnoringElementContentWhitespace(true);
  factory.setCoalescing(true);
  javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();

有没有办法让这个正则表达式在这个文件上运行并且正则表达式失败(因为它正确设置factory.setExpandEntityReferences(false);

更新:

(?:
   DocumentBuilderFactory
   \s+
   (\w+)
   \s*
   =
   \s*
   (?:.*?DocumentBuilderFactory)
   \s*.\s*
   newInstance.*
   (?:[\s\S](?!
      \1\s*.\s*
      (?:setFeature\s*\(\s*"http://xml.org/sax/features/external-general-entities"\s*,\s*false\s*\)
      |setFeature\s*\(\s*"http://apache.org/xml/features/disallow-doctype-decl"\s*,\s*false\s*\)
      |setExpandEntityReferences\s*\(\s*false\s*\))
   ))*$
)

正如预期的那样,它没有成功地找到();但是,如果我将 factory.setExpandEntityReferences(false) 拼错为 factory.setExpandEntity##References(false),我希望找到正则表达式,但事实并非如此。有没有办法让这个功能发挥作用?

4

1 回答 1

3

测试一个存在到末尾的字符串:

(?:.(?!xyz))*$

它的基本意思是,“从现在开始的每个字符,后面都不xyz能跟.”。由于.不匹配换行符,您可能希望将其概括为:

(?:[\s\S](?!xyz))*$
   ^^^^^^

(它是互补集的结合,因此是真正的所有角色。)

要将其应用于您的案例,只需替换xyz为您不希望出现在任何地方的内容:

   # checks that the var name is NOT (using ?!) using one of the acceptable rejection methods
   (?:[\s\S](?!
       \1[.\s]+
       (?:setFeature\s*\(\s*"http://xml.org/sax/features/external-general-entities"\s*,\s*false\s*\)
         |setFeature\s*\(\s*"http://apache.org/xml/features/disallow-doctype-decl"\s*,\s*false\s*\)
         |setExpandEntityReferences\s*\(\s*false\s*\))
   ))*$

使用单词边界来匹配整个单词(如标识符):

当然,在使用 时factory,你不会想要匹配old_factory!使用单词边界来确保您捕捉到整个单词。

在您的情况下,只需在\b之前添加一个\1

\b\1

简化您的字符类并转义文字点:

如评论中所述,\s包括\rand \n,因此您可以重写[\s\r\n]\s(不带括号)。

此外,您还想更改实例,例如

newInstance.*

newInstance[.]*

通配符的行为不像字符\s类或\w在字符类中:.仅表示字符类中的文字点。

于 2013-07-16T15:38:00.003 回答