1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <stdio.h> 8 9 #include <fuzz-utils/fuzzer.h> 10 #include <fuzz-utils/path.h> 11 #include <zircon/types.h> 12 13 #include "fuzzer-fixture.h" 14 15 namespace fuzzing { 16 namespace testing { 17 18 // |fuzzing::testing::Fuzzer| exposes internal APIs for testing and buffers output. 19 class TestFuzzer : public Fuzzer { 20 public: 21 TestFuzzer(); 22 ~TestFuzzer() override; 23 fixture()24 const FuzzerFixture& fixture() const { return fixture_; } 25 26 // Resets the out and err buffers to be unallocated. 27 void Reset() override; 28 29 // Sets up the test fuzzer to buffer output with a Zircon-standalone test fixture 30 bool InitZircon(); 31 32 // Sets up the test fuzzer to buffer output with a test fixture of Fuchsia packages 33 bool InitFuchsia(); 34 35 // Resets |test| and reconstructs it from the |cmdline| in the context of the current fixture. 36 zx_status_t Eval(const char* cmdline); 37 38 // Returns the value associated with the given |key|, or null if unset. GetOption(const char * key)39 const char* GetOption(const char* key) { return options().get(key); } 40 41 // Invoke the base method with the saved arguments. Run()42 zx_status_t Run() { return Fuzzer::Run(&args_); } 43 44 // Checks if the (case-insensitive) substring is in the buffered output 45 bool InStdOut(const char* needle); 46 bool InStdErr(const char* needle); 47 48 // Returns the index in "argv" of the arg produced from |fmt| and any variadic parameters, or -1 49 // if it isn't found. 50 int FindArg(const char* fmt, const fbl::String& arg); FindArg(const fbl::String & arg)51 int FindArg(const fbl::String& arg) { return FindArg("%s", arg); } 52 53 // Various fixture locations executable()54 const char* executable() const { return executable_.c_str(); } manifest()55 const char* manifest() const { return manifest_.c_str(); } dictionary()56 const char* dictionary() const { return dictionary_.c_str(); } data_path()57 const char* data_path() const { return data_path_.c_str(); } data_path(const char * relpath)58 fbl::String data_path(const char* relpath) { return data_path_.Join(relpath); } 59 60 // Expose parent class methods SetOption(const fbl::String & option)61 zx_status_t SetOption(const fbl::String& option) { return Fuzzer::SetOption(option); } SetOption(const fbl::String & key,const fbl::String & val)62 zx_status_t SetOption(const fbl::String& key, const fbl::String& val) { 63 return Fuzzer::SetOption(key, val); 64 } RebasePath(const fbl::String & package,Path * out)65 zx_status_t RebasePath(const fbl::String& package, Path* out) { 66 return Fuzzer::RebasePath(package, out); 67 } GetPackagePath(const fbl::String & package,Path * out)68 zx_status_t GetPackagePath(const fbl::String& package, Path* out) { 69 return Fuzzer::GetPackagePath(package, out); 70 } FindZirconFuzzers(const fbl::String & zircon_path,const fbl::String & target,StringMap * out)71 void FindZirconFuzzers(const fbl::String& zircon_path, const fbl::String& target, 72 StringMap* out) { 73 Fuzzer::FindZirconFuzzers(zircon_path, target, out); 74 } FindFuchsiaFuzzers(const fbl::String & package,const fbl::String & target,StringMap * out)75 void FindFuchsiaFuzzers(const fbl::String& package, const fbl::String& target, StringMap* out) { 76 Fuzzer::FindFuchsiaFuzzers(package, target, out); 77 } FindFuzzers(const fbl::String & name,StringMap * out)78 void FindFuzzers(const fbl::String& name, StringMap* out) { Fuzzer::FindFuzzers(name, out); } 79 80 // Exposes |Fuzzer::CheckProcess| optionally overriding the executable name to look for. 81 bool CheckProcess(zx_handle_t process, const char* executable = nullptr); 82 83 protected: 84 // Overrides |Fuzzer::Execute| to simply save the subprocess' command line without spawning it. 85 zx_status_t Execute() override; 86 87 private: 88 // Sets up the test fuzzer to buffer output without changing the test fixture 89 bool Init(); 90 91 // The current test fixture 92 FuzzerFixture fixture_; 93 94 // The arguments passed to the subprocess 95 StringList args_; 96 97 // Test info, captured by |Execute| 98 fbl::String executable_; 99 fbl::String manifest_; 100 fbl::String dictionary_; 101 Path data_path_; 102 103 // Output stream 104 FILE* out_; 105 char* outbuf_; 106 size_t outbuflen_; 107 108 // Error stream 109 FILE* err_; 110 char* errbuf_; 111 size_t errbuflen_; 112 }; 113 114 } // namespace testing 115 } // namespace fuzzing 116