<feed xmlns='http://www.w3.org/2005/Atom'>
<title>libplist/src/plist.c, branch 2.8.0</title>
<subtitle>Library to handle Apple Property List format files in binary or XML</subtitle>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/'/>
<entry>
<title>plist: fix inverted strcmp in string to boolean conversion</title>
<updated>2026-09-29T14:43:02+00:00</updated>
<author>
<name>Arpit Jain</name>
</author>
<published>2026-07-29T05:25:18+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=bd68e726e45c10fd223814eaf6129e1bb2f7b022'/>
<id>bd68e726e45c10fd223814eaf6129e1bb2f7b022</id>
<content type='text'>
plist_dict_get_bool() compared the string value with strcmp() but treated a
non-zero return as a match. strcmp() returns 0 on equality, so the conditions
were inverted: "true" produced 0, "false" produced 1, and any other string
also produced 1. The error branch could never be reached, since it required
both comparisons to return 0 at once.

The result is that the API returns the opposite of the stored value for both
valid boolean strings, and returns true for strings that are not booleans at
all, instead of reporting the conversion error.

Compare == 0 in both conditions:

  input          before   after
  true           0        1
  false          1        0
  not-a-bool     1        error
  TRUE           1        error
  (empty)        1        error

Signed-off-by: Arpit Jain &lt;arpitjain099@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
plist_dict_get_bool() compared the string value with strcmp() but treated a
non-zero return as a match. strcmp() returns 0 on equality, so the conditions
were inverted: "true" produced 0, "false" produced 1, and any other string
also produced 1. The error branch could never be reached, since it required
both comparisons to return 0 at once.

The result is that the API returns the opposite of the stored value for both
valid boolean strings, and returns true for strings that are not booleans at
all, instead of reporting the conversion error.

Compare == 0 in both conditions:

  input          before   after
  true           0        1
  false          1        0
  not-a-bool     1        error
  TRUE           1        error
  (empty)        1        error

Signed-off-by: Arpit Jain &lt;arpitjain099@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ptrarray: Handle realloc() failure in ptr_array_insert()</title>
<updated>2026-09-27T06:06:22+00:00</updated>
<author>
<name>Comtea04</name>
</author>
<published>2026-09-27T06:06:22+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=8b48fa72d359de89215f50cbf6ac8c77ae5de9b4'/>
<id>8b48fa72d359de89215f50cbf6ac8c77ae5de9b4</id>
<content type='text'>
ptr_array_insert() assigned the result of realloc() directly to
pa-&gt;pdata and bumped the capacity without checking for failure, so on
out-of-memory the old buffer was leaked and the following store or
memmove() wrote through a NULL pointer.

Keep the old buffer on failure and return -1 from ptr_array_insert()
and ptr_array_add(). The callers now handle the error:

- the array lookup cache (plist.c) is dropped instead of silently going
  out of sync with the node list; lookups then fall back to walking
  the children, as they do before the cache exists
- bplist parsing (used_indexes) and serialization (objects) return
  PLIST_ERR_NO_MEM; ignoring the error in parse_bin_node_at_index()
  would otherwise loop forever since the array never grows

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ptr_array_insert() assigned the result of realloc() directly to
pa-&gt;pdata and bumped the capacity without checking for failure, so on
out-of-memory the old buffer was leaked and the following store or
memmove() wrote through a NULL pointer.

Keep the old buffer on failure and return -1 from ptr_array_insert()
and ptr_array_add(). The callers now handle the error:

- the array lookup cache (plist.c) is dropped instead of silently going
  out of sync with the node list; lookups then fall back to walking
  the children, as they do before the cache exists
- bplist parsing (used_indexes) and serialization (objects) return
  PLIST_ERR_NO_MEM; ignoring the error in parse_bin_node_at_index()
  would otherwise loop forever since the array never grows

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>refactor: centralize formatting helpers and harden out-plutil</title>
<updated>2026-05-22T16:46:02+00:00</updated>
<author>
<name>Nikias Bassen</name>
</author>
<published>2026-05-22T16:46:02+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=9711459dbed7d60bb00c7d2c052623e8489c88e1'/>
<id>9711459dbed7d60bb00c7d2c052623e8489c88e1</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Add error handling to all modification functions</title>
<updated>2026-04-26T23:45:33+00:00</updated>
<author>
<name>Nikias Bassen</name>
</author>
<published>2026-04-26T23:45:33+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=d35b31d0a2661b6346a1592a5eb7b70e66b2a141'/>
<id>d35b31d0a2661b6346a1592a5eb7b70e66b2a141</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add OpenStep coercion support for non-OpenStep plist types</title>
<updated>2026-03-22T18:16:51+00:00</updated>
<author>
<name>Nikias Bassen</name>
</author>
<published>2026-03-22T18:16:51+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=c8b36a80bad4a1fe488927af4da0ecbcf10079bb'/>
<id>c8b36a80bad4a1fe488927af4da0ecbcf10079bb</id>
<content type='text'>
- 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
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- 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
</pre>
</div>
</content>
</entry>
<entry>
<title>Add JSON coercion support for non-JSON plist types</title>
<updated>2026-03-20T16:12:47+00:00</updated>
<author>
<name>Calil Khalil</name>
</author>
<published>2026-02-21T13:39:24+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=3edac28498d883f1f768699ee15ce85a82bb2a7b'/>
<id>3edac28498d883f1f768699ee15ce85a82bb2a7b</id>
<content type='text'>
- 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
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- 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
</pre>
</div>
</content>
</entry>
<entry>
<title>xplist: Convert nested {CF$UID:&lt;int&gt;} dicts to PLIST_UID safely</title>
<updated>2026-02-22T02:39:54+00:00</updated>
<author>
<name>Sami Kortelainen</name>
</author>
<published>2026-02-22T02:39:54+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=f5e74fc1e007b8f625d91e40c160785580de8f60'/>
<id>f5e74fc1e007b8f625d91e40c160785580de8f60</id>
<content type='text'>
Convert single-entry { "CF$UID" : &lt;integer&gt; } 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 &lt;sami.kortelainen@piceasoft.com&gt;
Co-authored-by: Nikias Bassen &lt;nikias@gmx.li&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Convert single-entry { "CF$UID" : &lt;integer&gt; } 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 &lt;sami.kortelainen@piceasoft.com&gt;
Co-authored-by: Nikias Bassen &lt;nikias@gmx.li&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>plist: make array and dict iterators opaque</title>
<updated>2026-02-12T01:10:19+00:00</updated>
<author>
<name>Nikias Bassen</name>
</author>
<published>2026-02-12T01:10:19+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=a7e82b846543a4fc8d3291a5a65dd66b0cb84396'/>
<id>a7e82b846543a4fc8d3291a5a65dd66b0cb84396</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add NULL checks across codebase</title>
<updated>2026-02-12T00:20:05+00:00</updated>
<author>
<name>Nikias Bassen</name>
</author>
<published>2026-02-12T00:20:05+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=4e82bc85671cfe50763de2637b54cb8576d7976f'/>
<id>4e82bc85671cfe50763de2637b54cb8576d7976f</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>plist: Make plist copy and free implementations iterative</title>
<updated>2026-02-10T16:45:12+00:00</updated>
<author>
<name>Nikias Bassen</name>
</author>
<published>2026-02-10T16:45:12+00:00</published>
<link rel='alternate' type='text/html' href='https://cgit.sukimashita.com/libplist.git/commit/?id=8c78d89041b713bffcb0b09fee4468304a3a54d5'/>
<id>8c78d89041b713bffcb0b09fee4468304a3a54d5</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
</feed>
