1 // Copyright 2021 The Tint Authors. 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 #ifndef FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_ 16 #define FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_ 17 18 #include <string> 19 #include <utility> 20 #include <vector> 21 22 #include "fuzzers/random_generator.h" 23 24 namespace tint { 25 namespace fuzzers { 26 namespace regex_fuzzer { 27 28 /// A function that given a delimiter, returns a vector that contains 29 /// all the positions of the delimiter in the WGSL code. 30 /// @param delimiter - the delimiter of the enclosed region. 31 /// @param wgsl_code - the initial string (WGSL code) that will be mutated. 32 /// @return a vector with the positions of the delimiter in the WGSL code. 33 std::vector<size_t> FindDelimiterIndices(const std::string& delimiter, 34 const std::string& wgsl_code); 35 36 /// A function that finds all the identifiers in a WGSL-like string. 37 /// @param wgsl_code - the WGSL-like string where the identifiers will be found. 38 /// @return a vector with the positions and the length of all the 39 /// identifiers in wgsl_code. 40 std::vector<std::pair<size_t, size_t>> GetIdentifiers( 41 const std::string& wgsl_code); 42 43 /// A function that returns returns the starting position 44 /// and the length of all the integer literals in a WGSL-like string. 45 /// @param wgsl_code - the WGSL-like string where the int literals 46 /// will be found. 47 /// @return a vector with the starting positions and the length 48 /// of all the integer literals. 49 std::vector<std::pair<size_t, size_t>> GetIntLiterals( 50 const std::string& wgsl_code); 51 52 /// Finds a possible closing brace corresponding to the opening 53 /// brace at position opening_bracket_pos. 54 /// @param opening_bracket_pos - the position of the opening brace. 55 /// @param wgsl_code - the WGSL-like string where the closing brace. 56 /// @return the position of the closing bracket or 0 if there is no closing 57 /// brace. 58 size_t FindClosingBrace(size_t opening_bracket_pos, 59 const std::string& wgsl_code); 60 61 /// Returns the starting_position of the bodies of the functions 62 /// that follow the regular expression: fn.*?->.*?\\{, which searches for the 63 /// keyword fn followed by the function name, its return type and opening brace. 64 /// @param wgsl_code - the WGSL-like string where the functions will be 65 /// searched. 66 /// @return a vector with the starting position of the function bodies in 67 /// wgsl_code. 68 std::vector<size_t> GetFunctionBodyPositions(const std::string& wgsl_code); 69 70 /// Given 4 indices, idx1, idx2, idx3 and idx4 it swaps the regions 71 /// in the interval (idx1, idx2] with the region in the interval (idx3, idx4] 72 /// in wgsl_text. 73 /// @param idx1 - starting index of the first region. 74 /// @param reg1_len - length of the first region. 75 /// @param idx2 - starting index of the second region. 76 /// @param reg2_len - length of the second region. 77 /// @param wgsl_code - the string where the swap will occur. 78 void SwapIntervals(size_t idx1, 79 size_t reg1_len, 80 size_t idx2, 81 size_t reg2_len, 82 std::string& wgsl_code); 83 84 /// Given index idx1 it delets the region of length interval_len 85 /// starting at index idx1; 86 /// @param idx1 - starting index of the first region. 87 /// @param reg_len - terminating index of the second region. 88 /// @param wgsl_code - the string where the swap will occur. 89 void DeleteInterval(size_t idx1, size_t reg_len, std::string& wgsl_code); 90 91 /// Given 2 indices, idx1, idx2, it inserts the region of length 92 /// reg1_len starting at idx1 after idx2. 93 /// @param idx1 - starting index of region. 94 /// @param reg1_len - length of the region. 95 /// @param idx2 - the position where the region will be inserted. 96 /// @param wgsl_code - the string where the swap will occur. 97 void DuplicateInterval(size_t idx1, 98 size_t reg1_len, 99 size_t idx2, 100 std::string& wgsl_code); 101 102 /// Replaces a region of a WGSL-like string of length id2_len starting 103 /// at position idx2 with a region of length id1_len starting at 104 /// position idx1. 105 /// @param idx1 - starting position of the first region. 106 /// @param id1_len - length of the first region. 107 /// @param idx2 - starting position of the second region. 108 /// @param id2_len - length of the second region. 109 /// @param wgsl_code - the string where the replacement will occur. 110 void ReplaceRegion(size_t idx1, 111 size_t id1_len, 112 size_t idx2, 113 size_t id2_len, 114 std::string& wgsl_code); 115 116 /// Replaces an interval of length `length` starting at start_index 117 /// with the `replacement_text`. 118 /// @param start_index - starting position of the interval to be replaced. 119 /// @param length - length of the interval to be replaced. 120 /// @param replacement_text - the interval that will be used as a replacement. 121 /// @param wgsl_code - the WGSL-like string where the replacement will occur. 122 void ReplaceInterval(size_t start_index, 123 size_t length, 124 std::string replacement_text, 125 std::string& wgsl_code); 126 127 /// A function that, given WGSL-like string and a delimiter, 128 /// generates another WGSL-like string by picking two random regions 129 /// enclosed by the delimiter and swapping them. 130 /// @param delimiter - the delimiter that will be used to find enclosed regions. 131 /// @param wgsl_code - the initial string (WGSL code) that will be mutated. 132 /// @param generator - the random number generator. 133 /// @return true if a swap happened or false otherwise. 134 bool SwapRandomIntervals(const std::string& delimiter, 135 std::string& wgsl_code, 136 RandomGenerator& generator); 137 138 /// A function that, given a WGSL-like string and a delimiter, 139 /// generates another WGSL-like string by deleting a random 140 /// region enclosed by the delimiter. 141 /// @param delimiter - the delimiter that will be used to find enclosed regions. 142 /// @param wgsl_code - the initial string (WGSL code) that will be mutated. 143 /// @param generator - the random number generator. 144 /// @return true if a deletion happened or false otherwise. 145 bool DeleteRandomInterval(const std::string& delimiter, 146 std::string& wgsl_code, 147 RandomGenerator& generator); 148 149 /// A function that, given a WGSL-like string and a delimiter, 150 /// generates another WGSL-like string by duplicating a random 151 /// region enclosed by the delimiter. 152 /// @param delimiter - the delimiter that will be used to find enclosed regions. 153 /// @param wgsl_code - the initial string (WGSL code) that will be mutated. 154 /// @param generator - the random number generator. 155 /// @return true if a duplication happened or false otherwise. 156 bool DuplicateRandomInterval(const std::string& delimiter, 157 std::string& wgsl_code, 158 RandomGenerator& generator); 159 160 /// Replaces a randomly-chosen identifier in wgsl_code. 161 /// @param wgsl_code - WGSL-like string where the replacement will occur. 162 /// @param generator - the random number generator. 163 /// @return true if a replacement happened or false otherwise. 164 bool ReplaceRandomIdentifier(std::string& wgsl_code, 165 RandomGenerator& generator); 166 167 /// Replaces the value of a randomly-chosen integer with one of 168 /// the values in the set {INT_MAX, INT_MIN, 0, -1}. 169 /// @param wgsl_code - WGSL-like string where the replacement will occur. 170 /// @param generator - the random number generator. 171 /// @return true if a replacement happened or false otherwise. 172 bool ReplaceRandomIntLiteral(std::string& wgsl_code, 173 RandomGenerator& generator); 174 175 /// Inserts a return statement in a randomly chosen function of a 176 /// WGSL-like string. The return value is a randomly-chosen identifier 177 /// or literal in the string. 178 /// @param wgsl_code - WGSL-like string that will be mutated. 179 /// @param generator - the random number generator. 180 /// @return true if the mutation was succesful or false otherwise. 181 bool InsertReturnStatement(std::string& wgsl_code, RandomGenerator& generator); 182 } // namespace regex_fuzzer 183 } // namespace fuzzers 184 } // namespace tint 185 186 #endif // FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_ 187