/* * plist_write_fuzzer.cc * plist writer fuzz target for libFuzzer * * Copyright (c) 2017 Nikias Bassen All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include static plist_format_t select_output_format(uint8_t mode) { switch (mode % 6) { case 0: return PLIST_FORMAT_XML; case 1: return PLIST_FORMAT_JSON; case 2: return PLIST_FORMAT_OSTEP; case 3: return PLIST_FORMAT_PRINT; case 4: return PLIST_FORMAT_LIMD; default: return PLIST_FORMAT_PLUTIL; } } static plist_write_options_t select_options(uint8_t opt) { unsigned int options = PLIST_OPT_NONE; if (opt & 0x01) { options |= PLIST_OPT_COMPACT; } if (opt & 0x02) { options |= PLIST_OPT_COERCE; } if (opt & 0x04) { options |= PLIST_OPT_NO_NEWLINE; } if (opt & 0x08) { options |= PLIST_OPT_PARTIAL_DATA; } if (opt & 0x10) { options |= PLIST_OPT_INDENT; options |= PLIST_OPT_INDENT_BY(1); } return static_cast(options); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (!data || size < 3 || size > 4096) { return 0; } const uint8_t mode = data[size - 2]; const uint8_t opt = data[size - 1]; plist_t root = NULL; plist_format_t in_format = PLIST_FORMAT_NONE; plist_err_t err = plist_from_memory( reinterpret_cast(data), static_cast(size - 2), &root, &in_format ); if (err != PLIST_ERR_SUCCESS || !root) { plist_free(root); return 0; } char* output = NULL; uint32_t output_len = 0; (void)plist_write_to_string( root, &output, &output_len, select_output_format(mode), select_options(opt) ); plist_mem_free(output); plist_free(root); return 0; }