• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 Code Intelligence GmbH
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.example;
16 
17 import com.code_intelligence.jazzer.api.FuzzedDataProvider;
18 import com.code_intelligence.jazzer.api.FuzzerSecurityIssueLow;
19 import java.util.regex.Pattern;
20 
21 public class RegexRoadblocks {
22   // We accept arbitrary suffixes but not prefixes for the following reasons:
23   // 1. The fuzzer will take much longer to match the exact length of the input than to satisfy the
24   //    compare checks, which is what we really want to test.
25   // 2. Accepting arbitrary prefixes could lead to tests passing purely due to ToC entries being
26   //    emitted in arbitrary positions, but we want to ensure that compares are correctly reported
27   //    including position hints.
28   private static final Pattern LITERAL = Pattern.compile("foobarbaz.*");
29   private static final Pattern QUOTED_LITERAL = Pattern.compile(Pattern.quote("jazzer_is_cool.*"));
30   private static final Pattern CASE_INSENSITIVE_LITERAL =
31       Pattern.compile("JaZzER!.*", Pattern.CASE_INSENSITIVE);
32   private static final Pattern GROUP = Pattern.compile("(always).*");
33   private static final Pattern ALTERNATIVE = Pattern.compile("(to_be|not_to_be).*");
34   private static final Pattern SINGLE_LATIN1_CHAR_PROPERTY = Pattern.compile("[€].*");
35   private static final Pattern MULTIPLE_LATIN1_CHAR_PROPERTY = Pattern.compile("[ẞÄ].*");
36   private static final Pattern RANGE_LATIN1_CHAR_PROPERTY = Pattern.compile("[¢-¥].*");
37 
38   private static int run = 0;
39 
40   private static boolean matchedLiteral = false;
41   private static boolean matchedQuotedLiteral = false;
42   private static boolean matchedCaseInsensitiveLiteral = false;
43   private static boolean matchedGroup = false;
44   private static boolean matchedAlternative = false;
45   private static boolean matchedSingleLatin1CharProperty = false;
46   private static boolean matchedMultipleLatin1CharProperty = false;
47   private static boolean matchedRangeLatin1CharProperty = false;
48 
fuzzerTestOneInput(FuzzedDataProvider data)49   public static void fuzzerTestOneInput(FuzzedDataProvider data) {
50     run++;
51     String input = data.consumeRemainingAsString();
52 
53     if (!matchedLiteral && LITERAL.matcher(input).matches()) {
54       System.out.println("Cleared LITERAL");
55       matchedLiteral = true;
56     } else if (!matchedQuotedLiteral && QUOTED_LITERAL.matcher(input).matches()) {
57       System.out.println("Cleared QUOTED_LITERAL");
58       matchedQuotedLiteral = true;
59     } else if (!matchedCaseInsensitiveLiteral
60         && CASE_INSENSITIVE_LITERAL.matcher(input).matches()) {
61       System.out.println("Cleared CASE_INSENSITIVE_LITERAL");
62       matchedCaseInsensitiveLiteral = true;
63     } else if (!matchedGroup && GROUP.matcher(input).matches()) {
64       System.out.println("Cleared GROUP");
65       matchedGroup = true;
66     } else if (!matchedAlternative && ALTERNATIVE.matcher(input).matches()) {
67       System.out.println("Cleared ALTERNATIVE");
68       matchedAlternative = true;
69     } else if (!matchedSingleLatin1CharProperty
70         && SINGLE_LATIN1_CHAR_PROPERTY.matcher(input).matches()) {
71       System.out.println("Cleared SINGLE_LATIN1_CHAR_PROPERTY");
72       matchedSingleLatin1CharProperty = true;
73     } else if (!matchedMultipleLatin1CharProperty
74         && MULTIPLE_LATIN1_CHAR_PROPERTY.matcher(input).matches()) {
75       System.out.println("Cleared MULTIPLE_LATIN1_CHAR_PROPERTY");
76       matchedMultipleLatin1CharProperty = true;
77     } else if (!matchedRangeLatin1CharProperty
78         && RANGE_LATIN1_CHAR_PROPERTY.matcher(input).matches()) {
79       System.out.println("Cleared RANGE_LATIN1_CHAR_PROPERTY");
80       matchedRangeLatin1CharProperty = true;
81     }
82 
83     if (matchedLiteral && matchedQuotedLiteral && matchedCaseInsensitiveLiteral && matchedGroup
84         && matchedAlternative && matchedSingleLatin1CharProperty
85         && matchedMultipleLatin1CharProperty && matchedRangeLatin1CharProperty) {
86       throw new FuzzerSecurityIssueLow("Fuzzer matched all regexes in " + run + " runs");
87     }
88   }
89 }
90