| /* |
| * 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 <plist/plist.h> |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| 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<plist_write_options_t>(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<const char*>(data), |
| static_cast<uint32_t>(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; |
| } |