Skip to content

Commit

Permalink
Add level 02 of puzzle using multiple if conditions on integer statem…
Browse files Browse the repository at this point in the history
…ents.

This can be found by the fuzzing engine in ~30s.

PiperOrigin-RevId: 604765858
  • Loading branch information
Markus Kusano authored and copybara-github committed Feb 13, 2024
1 parent 8c636aa commit 3780f0b
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 2 deletions.
190 changes: 188 additions & 2 deletions e2e_tests/testdata/fuzz_tests_with_proto_inputs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cstdint>
#include <cstdlib>
#include <limits>
#include <vector>
Expand All @@ -24,11 +25,24 @@ namespace {
using fuzztest::internal::CalculatorExpression;
using fuzztest::internal::FoodMachineProcedure;
using fuzztest::internal::RoboCourier560Plan;
using fuzztest::internal::SingleBytesField;
using fuzztest::internal::TestProtobuf;

void BytesSummingToMagicValueWithOverloadedProto(const TestProtobuf& input) {
void BytesSummingToMagicValue(const SingleBytesField& input) {
char sum = 0;
for (const char c : input.str()) {
for (const char c : input.data()) {
sum += c;
}
if (sum == 0x72) {
std::abort();
}
}
FUZZ_TEST(ProtoPuzzles, BytesSummingToMagicValue);

void BytesSummingToMagicValueWithOverloadedProto(
const SingleBytesField& input) {
char sum = 0;
for (const char c : input.data()) {
sum += c;
}
if (sum == 0x72) {
Expand All @@ -37,6 +51,16 @@ void BytesSummingToMagicValueWithOverloadedProto(const TestProtobuf& input) {
}
FUZZ_TEST(ProtoPuzzles, BytesSummingToMagicValueWithOverloadedProto);

void PrefixBytesSummingToMagicValue(const SingleBytesField& input) {
if (input.data().size() < 2) {
return;
}
if (input.data()[0] + input.data()[1] == 0x72) {
std::abort();
}
}
FUZZ_TEST(ProtoPuzzles, PrefixBytesSummingToMagicValue);

void PrefixBytesSummingToMagicValueWithOverloadedProto(
const TestProtobuf& input) {
if (input.str().size() < 2) {
Expand All @@ -48,6 +72,16 @@ void PrefixBytesSummingToMagicValueWithOverloadedProto(
}
FUZZ_TEST(ProtoPuzzles, PrefixBytesSummingToMagicValueWithOverloadedProto);

void PrefixIsMagicValue(const SingleBytesField& input) {
if (input.data().size() < 2) {
return;
}
if (input.data()[0] + input.data()[1] == 0x72) {
std::abort();
}
}
FUZZ_TEST(ProtoPuzzles, PrefixIsMagicValue);

void PrefixIsMagicValueWithOverloadedProto(const TestProtobuf& input) {
if (input.str().size() < 2) {
return;
Expand All @@ -58,6 +92,29 @@ void PrefixIsMagicValueWithOverloadedProto(const TestProtobuf& input) {
}
FUZZ_TEST(ProtoPuzzles, PrefixIsMagicValueWithOverloadedProto);

void ContainsCharactersSpecifiedAtStartOfString(const SingleBytesField& input) {
if (input.data().size() < 2) {
return;
}
char quantity = input.data()[0];
char to_find = input.data()[1];

if (to_find == 0) {
return;
}

char num_found = 0;
for (int i = 2; i < input.data().size(); ++i) {
if (input.data()[i] == to_find) {
num_found++;
}
}
if (num_found == quantity) {
abort();
}
}
FUZZ_TEST(ProtoPuzzles, ContainsCharactersSpecifiedAtStartOfString);

void ContainsCharactersSpecifiedAtStartOfStringWithOverloadedProto(
const TestProtobuf& input) {
if (input.str().size() < 2) {
Expand Down Expand Up @@ -248,4 +305,133 @@ void RunRoboCourier560(const RoboCourier560Plan& plan) {
}
FUZZ_TEST(ProtoPuzzles, RunRoboCourier560);

void IntegerConditionsOnTestProtobufLevel00(const TestProtobuf& input) {
int64_t integer_result;
if (input.b()) {
if (__builtin_add_overflow(input.i32(), input.i64(), &integer_result)) {
return; // [Hint] Overflow detected
}
} else {
if (__builtin_sub_overflow(input.i32(), input.i64(), &integer_result)) {
return; // [Hint] Overflow detected
}
}
if (integer_result < 1239291904) {
return;
}

if (input.rep_b().empty()) {
return;
}
uint64_t unsigned_result;
if (input.rep_b()[0]) {
unsigned_result = input.u32() + input.u64() + input.rep_b()[0];
} else {
unsigned_result = input.u32() - input.u64() - input.rep_b()[0];
}
if (unsigned_result != 2000) {
return;
}
// [Hint] Reachable if all of the early returns above are not taken.
std::abort();
}
FUZZ_TEST(ProtoPuzzles, IntegerConditionsOnTestProtobufLevel00);

void IntegerConditionsOnTestProtobufLevel01(const TestProtobuf& input) {
int64_t integer_result;
if (input.b()) {
if (__builtin_add_overflow(input.i32(), input.i64(), &integer_result)) {
return; // [Hint] Overflow detected
}
} else {
if (__builtin_sub_overflow(input.i32(), input.i64(), &integer_result)) {
return; // [Hint] Overflow detected
}
}
if (integer_result < 1239291904) {
return;
}

if (input.rep_b().empty()) {
return;
}
if (input.rep_b().size() < 5) {
return;
}
bool flip = false;
uint32_t num_trues = 0;
for (const bool& b : input.rep_b()) {
flip += b;
num_trues += b;
}
uint64_t unsigned_result;
if (flip) {
unsigned_result = input.u32() + input.u64() + num_trues;
} else {
unsigned_result = input.u32() - input.u64() + num_trues;
}
if (unsigned_result != 2000) {
return;
}
// [Hint] reachable if none of the early returns above are taken.
std::abort();
}
FUZZ_TEST(ProtoPuzzles, IntegerConditionsOnTestProtobufLevel01);

void IntegerConditionsOnTestProtobufLevel02(const TestProtobuf& input) {
int64_t integer_result;
if (input.b()) {
if (__builtin_add_overflow(input.i32(), input.i64(), &integer_result)) {
return; // [Hint] Overflow detected
}
} else {
if (__builtin_sub_overflow(input.i32(), input.i64(), &integer_result)) {
return; // [Hint] Overflow detected
}
}
if (integer_result < 1239291904) {
return;
}

if (input.rep_b().empty()) {
return;
}
if (input.rep_b().size() < 5) {
return;
}
bool flip = false;
uint32_t num_trues = 0;
for (const bool& b : input.rep_b()) {
flip += b;
num_trues += b;
}
uint64_t unsigned_result;
if (flip) {
unsigned_result = input.u32() + input.u64() + num_trues;
} else {
unsigned_result = input.u32() - input.u64() + num_trues;
}
if (unsigned_result != 2000) {
return;
}

uint64_t rep_u32_result = 0;
if (input.rep_u32().size() < 10) {
return;
}
for (int i = 0; i < input.rep_u32().size(); ++i) {
if (input.rep_b()[i % input.rep_b().size()]) {
rep_u32_result += input.rep_u32()[i];
} else {
rep_u32_result -= input.rep_u32()[i];
}
}
if (rep_u32_result < 65377) {
return;
}
// [Hint] Can happen if none of the early returns above are taken.
std::abort();
}
FUZZ_TEST(ProtoPuzzles, IntegerConditionsOnTestProtobufLevel02);

} // namespace
4 changes: 4 additions & 0 deletions fuzztest/internal/test_protobuf.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ enum BareEnum {
LABEL_OTHER = 10;
}

message SingleBytesField {
optional bytes data = 1;
}

message TestSubProtobuf {
optional int32 subproto_i32 = 1;
repeated int32 subproto_rep_i32 = 2 [packed = true];
Expand Down

0 comments on commit 3780f0b

Please sign in to comment.