| 144 | } |
| 145 | |
| 146 | size_t LLVMFuzzerCustomCrossOver(const u8 *in1, size_t in1_size, const u8 *in2, |
| 147 | size_t in2_size, u8 *out, size_t max_out_size, |
| 148 | unsigned seed) |
| 149 | { |
| 150 | if (in1_size < 9 || in2_size < 9) |
| 151 | return 0; |
| 152 | |
| 153 | // Interpret fuzz inputs as string (ensure it's null terminated). |
| 154 | char *input1 = to_string(tmpctx, in1, in1_size); |
| 155 | char *input2 = to_string(tmpctx, in2, in2_size); |
| 156 | |
| 157 | const size_t max_hrp1 = strlen(input1) - 6; |
| 158 | const size_t max_hrp2 = strlen(input2) - 6; |
| 159 | const size_t max_data1 = max_hrp1 - 2; |
| 160 | const size_t max_data2 = max_hrp2 - 2; |
| 161 | |
| 162 | // Attempt to bech32 decode the inputs. |
| 163 | char *hrp1 = tal_arr(tmpctx, char, max_hrp1); |
| 164 | char *hrp2 = tal_arr(tmpctx, char, max_hrp2); |
| 165 | u5 *data1 = tal_arr(tmpctx, u5, max_data1); |
| 166 | u5 *data2 = tal_arr(tmpctx, u5, max_data2); |
| 167 | |
| 168 | size_t data1_len = 0; |
| 169 | if (bech32_decode(hrp1, data1, &data1_len, input1, (size_t)-1) != |
| 170 | BECH32_ENCODING_BECH32) |
| 171 | // Decoding failed, this should only happen when starting from |
| 172 | // an empty corpus. |
| 173 | return 0; |
| 174 | size_t data2_len = 0; |
| 175 | if (bech32_decode(hrp2, data2, &data2_len, input2, (size_t)-1) != |
| 176 | BECH32_ENCODING_BECH32) |
| 177 | // Decoding failed, this should only happen when starting from |
| 178 | // an empty corpus. |
| 179 | return 0; |
| 180 | |
| 181 | srand(seed); |
| 182 | char *out_hrp; |
| 183 | u5 *out_data; |
| 184 | size_t out_data_len; |
| 185 | if (rand() % 2) { |
| 186 | // Cross-over the HRP. |
| 187 | out_data = data1; |
| 188 | out_data_len = data1_len; |
| 189 | |
| 190 | size_t max_out_hrp_size = max_out_size - data1_len - 8; |
| 191 | out_hrp = tal_arr(tmpctx, char, max_out_hrp_size + 1); |
| 192 | |
| 193 | size_t out_hrp_size = cross_over( |
| 194 | (u8 *)hrp1, strlen(hrp1), (u8 *)hrp2, strlen(hrp2), |
| 195 | (u8 *)out_hrp, max_out_hrp_size, (unsigned)rand()); |
| 196 | out_hrp[out_hrp_size] = '\0'; |
| 197 | } else { |
| 198 | // Cross-over the data part. |
| 199 | out_hrp = hrp1; |
| 200 | |
| 201 | size_t max_out_data_size = max_out_size - strlen(hrp1) - 8; |
| 202 | out_data = tal_arr(tmpctx, u5, max_out_data_size); |
| 203 |
nothing calls this directly
no test coverage detected