1079 Commits

Author SHA1 Message Date
Nikias Bassen 32428abacb [github-actions] Updated build workflow 2026-05-23 00:52:53 +02:00
Nikias Bassen bd851a87ec Print debug error message when encoutering invalid PLIST_DATE values 2026-05-22 20:41:23 +02:00
Nikias Bassen 024864926b bplist: Use format macro to use correct format in error message 2026-05-22 19:23:23 +02:00
Nikias Bassen ba82092e43 common: validate PLIST_DATE values before Time64_T conversion
Avoid undefined behavior when serializing malformed PLIST_DATE values
containing NaN, infinity, or values outside the Time64_T range. Add a
shared helper for checked date conversion and use it across writer paths.
2026-05-22 19:20:51 +02:00
Nikias Bassen 9711459dbe refactor: centralize formatting helpers and harden out-plutil 2026-05-22 18:46:02 +02:00
Nikias Bassen 389fab9a07 out-default: harden node serialization paths
Improve robustness and memory safety in node_to_string() and dtostr():

- add missing NULL and allocation checks
- fix snprintf() error handling and signed/unsigned conversions
- replace sprintf() with snprintf()
- fix base64 buffer sizing
- switch string offset tracking to size_t
- improve malformed data handling for strings and data blobs
2026-05-22 16:37:57 +02:00
Nikias Bassen 5546a87465 out-limd: Properly handle snprintf and some smaller improvements 2026-05-22 15:46:37 +02:00
Nikias Bassen 9d4f14a0ba out-limd: Fix memory buffer allocation size (#313)
Credit to @Bri1987
2026-05-22 15:00:16 +02:00
Nikias Bassen d35b31d0a2 Add error handling to all modification functions
Convert all array/dict modification functions from void to plist_err_t return type:
  - plist_array_set_item: replace at index n
  - plist_array_append_item: append to end
  - plist_array_insert_item: insert at position n
  - plist_array_remove_item: remove item at index n
  - plist_array_item_remove: remove item from its array parent
  - plist_dict_set_item: replace or insert key/value
  - plist_dict_remove_item: remove key/value pair
  - plist_dict_merge: merge source dict into target

Returns:
  - PLIST_ERR_SUCCESS on success
  - PLIST_ERR_INVALID_ARG for invalid arguments (NULL, wrong type, out of range, etc.)
  - PLIST_ERR_NO_MEM on memory allocation failure
  - PLIST_ERR_UNKNOWN on unexpected internal errors

Header documentation updated with full error code semantics for each function.
2026-04-27 01:45:33 +02:00
Dave Nicolson dddb76d74a Add OpenStep to man page 2026-04-10 12:21:50 +02:00
Nikias Bassen 9dfcfe8dc2 Fix fread() unused return values by actually handling errors 2026-04-10 12:21:17 +02:00
Dave Nicolson f41b1ea670 Fix Cython crashes 2026-03-30 20:21:22 +02:00
Nikias Bassen c8b36a80ba Add OpenStep coercion support for non-OpenStep plist types
- Use PLIST_OPT_COERCE option to coerce PLIST_BOOLEAN, PLIST_DATE, PLIST_UID, and PLIST_NULL to OpenStep-compatible types (1 or 0, ISO 8601 strings, integers, and 'NULL' string)
- Add plist_to_openstep_with_options() function to allow passing coercion option (and others)
- Update plist_write_to_string() and plist_write_to_stream() accordingly
2026-03-22 19:16:51 +01:00
Calil Khalil 3edac28498 Add JSON coercion support for non-JSON plist types
- Add PLIST_OPT_COERCE option to coerce PLIST_DATE, PLIST_DATA, and PLIST_UID to JSON-compatible types (ISO 8601 strings, Base64 strings, and integers)
- Add plist_to_json_with_options() function to allow passing coercion options (and others)
- Update plist_write_to_string() and plist_write_to_stream() to support coercion option
- Add --coerce flag to plistutil for JSON output
- Create plist2json symlink that automatically enables coercion when invoked
2026-03-20 17:12:47 +01:00
Sami Kortelainen 6e03a1df6d xplist: Enforce single root value inside <plist>
Ensure that XML property lists contain exactly one root value inside the <plist> element and reject any additional value nodes before </plist>.

Add tests covering root value handling and nested CF$UID conversion behavior.

Co-authored-by: Sami Kortelainen <sami.kortelainen@piceasoft.com>
Co-authored-by: Nikias Bassen <nikias@gmx.li>
2026-02-25 02:27:00 +01:00
Sami Kortelainen f5e74fc1e0 xplist: Convert nested {CF$UID:<int>} dicts to PLIST_UID safely
Convert single-entry { "CF$UID" : <integer> } dictionaries to PLIST_UID
nodes when closing a dict in the XML parser.

Refactor node cleanup logic:
- Split plist_free_data() into internal _plist_free_data()
- Introduce plist_free_children() to release child nodes separately
- Update plist_set_element_val() to free children before changing
  container node types
- Ensure PLIST_DICT hashtables do not free values (assert + force
  free_func = NULL)

This avoids in-place container mutation issues and ensures child
nodes and container metadata are released correctly before
changing node type.

Co-authored-by: Sami Kortelainen <sami.kortelainen@piceasoft.com>
Co-authored-by: Nikias Bassen <nikias@gmx.li>
2026-02-22 03:39:54 +01:00
Nikias Bassen 3bdee70a9c plistutil: Read STDIN in chunks instead of 1 byte at a time 2026-02-20 05:17:32 +01:00
Nikias Bassen e3d5bbdf1f plistutil: Add a --nodepath option to allow selecting a specific node 2026-02-20 03:38:36 +01:00
Nikias Bassen 30132a9e2c plistutil: Use getopt for solid option parsing 2026-02-20 02:32:19 +01:00
Nikias Bassen d5a582e95a json: Fix a few memory leaks 2026-02-13 01:05:53 +01:00
Nikias Bassen 70fd355f94 libcnary: Fix leak on error in node_copy_deep() 2026-02-13 00:48:34 +01:00
Nikias Bassen 9969b8ebeb bplist: Add overflow check to node offset pointer arithmetic
Credit to OSSFuzz
2026-02-12 02:43:50 +01:00
Nikias Bassen c4763002d2 jplist: Add another NULL check to prevent NULL pointer dereference 2026-02-12 02:14:45 +01:00
Nikias Bassen a7e82b8465 plist: make array and dict iterators opaque
Introduce private iterator structs for plist_array_iter and
plist_dict_iter, and fix *_next_item() to properly advance
iterator state and handle malformed containers safely.
2026-02-12 02:10:19 +01:00
Nikias Bassen 4e82bc8567 Add NULL checks across codebase 2026-02-12 01:20:05 +01:00
Nikias Bassen 8c78d89041 plist: Make plist copy and free implementations iterative
Convert plist_free_node() and plist_copy_node() to iterative
implementations. This avoids unbounded recursion and stack
overflow when handling deeply nested plist data, while
preserving existing semantics and caches.
2026-02-10 17:45:12 +01:00
Nikias Bassen 9ef0d05265 plist: Handle node_attach/node_insert failures
Update plist array and dict mutation helpers to check
return values from node_attach() and node_insert(). This
prevents cache corruption and allows new depth and cycle
checks to be enforced correctly.
2026-02-08 04:31:01 +01:00
Nikias Bassen 714ef4f956 libcnary: Fix node_detach to fully clear parent relationship
Ensure node_detach() clears child->parent after removal and
handles missing children lists safely. This makes detached
nodes reusable and allows correct rollback when reinserting
nodes after failed inserts (e.g. depth-limit failures).

Without this, detached nodes could remain logically parented,
causing inconsistent state and preventing reinsertion.
2026-02-08 03:54:06 +01:00
Nikias Bassen 1df039994f libcnary: Define error codes and add cycle, depth, and parent guards 2026-02-06 22:08:39 +01:00
Nikias Bassen b7f09ccddd xplist: Improve robustness of XML text parsing and value conversion
This change adds stricter validation for numeric and date nodes,
including full-input consumption, overflow/range checks, and rejection
of invalid floating-point values. Whitespace handling is clarified by
explicitly trimming trailing XML whitespace for value nodes.
2026-01-29 17:45:01 +01:00
Nikias Bassen ebf24567ea xplist: Use small stack buffer instead of dynamic allocations
This removes the necessity for malloc failures and reduces overhead
2026-01-26 18:56:41 +01:00
Nikias Bassen 57664f6394 plistutil: Make sure to check for memory allocation failure
Addresses #302.

Credit to @ylwango613.
2026-01-23 16:35:54 +01:00
Nikias Bassen d0e6ef114a plist: Improve plist_dict_get_item() to safely iterate key/value pairs
Use explicit key/value stepping, zero-initialize hash lookup key,
and perform length-checked comparisons on NUL-terminated key strings.
2026-01-23 16:20:55 +01:00
Nikias Bassen 1d628bc5b0 bplist: Fix compiler warning with explicit cast
Credit to @ylwango613
2026-01-22 13:29:11 +01:00
Rosen Penev 287e7e7fd6 time64: Add time_s support for WIN32
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2026-01-22 13:26:30 +01:00
Nikias Bassen 06d92b1152 plist: Fix plist_is_binary() not checking for NULL input
Fixes issue #300

Credit to @jasonmli8
2026-01-22 13:16:28 +01:00
Nikias Bassen 2b5b43bdb3 xplist: Use memcpy instead of strncpy since we know the exact size 2026-01-22 13:12:45 +01:00
Nikias Bassen ac7b64160f xplist: Harden entity unescaping against malformed input
- Fix numeric character reference parsing
- Enforce exact entity name matching
- Guard against size_t underflow and oversized entities
- Reject invalid Unicode code points
2026-01-22 13:12:05 +01:00
Nikias Bassen 502eb2a102 bplist: Fix is_ascii_string by using sufficiently large data type
Fixes #285

Credit to @ylwango613 for reporting.
2026-01-21 18:28:45 +01:00
Nikias Bassen 80c2fe8073 bplist: Fix UTF-8 to UTF-16 decoding and enforce strict validation
- Treat input as unsigned bytes
- Correct UTF-8 bit decoding for 2/3/4-byte sequences
- Add overlong, surrogate, and range checks
- Enforce lead/continuation byte constraints

This addresses issue #283.

Credit to @hgarrereyn for reporting.
2026-01-21 18:22:13 +01:00
Nikias Bassen f06c4c6b6c plist: Fix incorrect size storage in plist_copy() for PLIST_STRING nodes 2026-01-21 17:33:53 +01:00
Nikias Bassen c0f9df912d jsmn: use size_t for token offsets and harden against overflow
Use size_t for token start/end offsets instead of int, replace the -1
sentinel with SIZE_MAX, and add a defensive guard against offset
wraparound. This prevents overflow when parsing very large JSON inputs.

This addresses issue #282.

Credit to @ylwango613 for repporting.
2026-01-21 12:26:13 +01:00
Nikias Bassen c18d6b323e plist: Fix heap overflow caused by incorrect PLIST_STRING length during copy
Credit to @LkkkLxy. Addresses #277.
2026-01-20 15:15:17 +01:00
Nikias Bassen cff6a14ba4 plist: Reject insertion of plist nodes that already have a parent
Credit to @LkkkLxy for reporting (#276).

libplist nodes are owned by exactly one container. Inserting the same
plist_t into multiple dicts or arrays corrupts the tree structure and
leads to use-after-free crashes during traversal or plist_free().

Add explicit parent checks to dict and array insertion APIs to reject
nodes that already belong to another container. In debug builds, this
fails loudly via assert() and optional diagnostics; in release builds,
the operation safely no-ops.

Callers that need to reuse values must create a copy using plist_copy()
or explicitly detach the node before reinserting it.
2026-01-20 09:55:40 +01:00
Nikias Bassen 001a59eef3 plistutil: Use proper error description for new error codes 2026-01-17 16:35:19 +01:00
Nikias Bassen e45099fb21 Prevent deep nesting of plist structures in all input/output formats
Thanks to @unbengable12 for reporting. Addresses #288, #289, #290, #291, and #292.
2026-01-17 16:04:00 +01:00
Nikias Bassen 26dd27c435 bplist: Fix format specifier in debug message 2026-01-14 03:08:53 +01:00
Nikias Bassen 5b3ae4c132 Add circular reference detection to all format writers
Thanks to @LkkkLxy for pointing out the issue.
2026-01-14 02:50:40 +01:00
Nikias Bassen 25d61ff8b5 hashtable: Remove unnecessary casts by using the correct type for the next member 2026-01-12 12:13:01 +01:00
Nikias Bassen c74e34edda plist: make plist_data_compare NULL-safe
Ensure plist_data_compare safely handles NULL inputs by normalizing
NULL data to empty values and avoiding invalid dereferences.
2026-01-12 01:32:25 +01:00