summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am9
-rw-r--r--test/data/1.plist6
-rwxr-xr-xtest/json-invalid-types.test6
-rwxr-xr-xtest/ostep-invalid-types.test9
-rwxr-xr-xtest/xml_behavior.test2
-rw-r--r--test/xml_behavior_test.c167
6 files changed, 186 insertions, 13 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index a4191c4..f9f21e4 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,7 +13,8 @@ noinst_PROGRAMS = \
integer_set_test \
plist_btest \
plist_jtest \
- plist_otest
+ plist_otest \
+ xml_behavior_test
plist_cmp_SOURCES = plist_cmp.c
plist_cmp_LDADD = \
@@ -38,6 +39,9 @@ plist_jtest_LDADD = $(top_builddir)/src/libplist-2.0.la
plist_otest_SOURCES = plist_otest.c
plist_otest_LDADD = $(top_builddir)/src/libplist-2.0.la
+xml_behavior_test_SOURCES = xml_behavior_test.c
+xml_behavior_test_LDADD = $(top_builddir)/src/libplist-2.0.la
+
TESTS = \
empty.test \
small.test \
@@ -79,7 +83,8 @@ TESTS = \
ostep2.test \
ostep-strings.test \
ostep-comments.test \
- ostep-invalid-types.test
+ ostep-invalid-types.test \
+ xml_behavior.test
EXTRA_DIST = \
$(TESTS) \
diff --git a/test/data/1.plist b/test/data/1.plist
index e6e275d..82a112b 100644
--- a/test/data/1.plist
+++ b/test/data/1.plist
@@ -23,11 +23,11 @@
<key>Another Boolean</key>
<true/>
<key>Some Int</key>
- <integer></integer>
+ <integer>0</integer>
<key>Some Real</key>
- <real></real>
+ <real>1e4</real>
<key>Some Date</key>
- <date></date>
+ <date>1970-01-01T00:00:00Z</date>
<key>Some Data</key>
<data>
</data>
diff --git a/test/json-invalid-types.test b/test/json-invalid-types.test
index c532316..a21fcd9 100755
--- a/test/json-invalid-types.test
+++ b/test/json-invalid-types.test
@@ -14,19 +14,19 @@ export PLIST_JSON_DEBUG=1
echo "Converting (failure expected)"
$top_builddir/tools/plistutil -f json -i $DATASRC/$TESTFILE0 -o /dev/null
-if [ $? -neq 2 ]; then
+if [ $? -ne 2 ]; then
exit 1
fi
echo "Converting (failure expected)"
$top_builddir/tools/plistutil -f json -i $DATASRC/$TESTFILE1 -o /dev/null
-if [ $? -neq 2 ]; then
+if [ $? -ne 2 ]; then
exit 2
fi
echo "Converting (failure expected)"
$top_builddir/tools/plistutil -f json -i $DATASRC/$TESTFILE2 -o /dev/null
-if [ $? -neq 2 ]; then
+if [ $? -ne 2 ]; then
exit 3
fi
diff --git a/test/ostep-invalid-types.test b/test/ostep-invalid-types.test
index 9222394..3ae376c 100755
--- a/test/ostep-invalid-types.test
+++ b/test/ostep-invalid-types.test
@@ -2,7 +2,6 @@
DATASRC=$top_srcdir/test/data
DATAOUT=$top_builddir/test/data
-TESTFILE0=data.bplist
TESTFILE1=7.plist
TESTFILE2=uid.bplist
@@ -13,20 +12,20 @@ fi
export PLIST_OSTEP_DEBUG=1
echo "Converting (failure expected)"
-$top_builddir/tools/plistutil -f openstep -i $DATASRC/$TESTFILE0 -o /dev/null
-if [ $? -neq 2 ]; then
+echo '[true]' |$top_builddir/tools/plistutil -f openstep -i - -o /dev/null
+if [ $? -ne 2 ]; then
exit 1
fi
echo "Converting (failure expected)"
$top_builddir/tools/plistutil -f openstepn -i $DATASRC/$TESTFILE1 -o /dev/null
-if [ $? -neq 2 ]; then
+if [ $? -ne 2 ]; then
exit 2
fi
echo "Converting (failure expected)"
$top_builddir/tools/plistutil -f openstep -i $DATASRC/$TESTFILE2 -o /dev/null
-if [ $? -neq 2 ]; then
+if [ $? -ne 2 ]; then
exit 3
fi
diff --git a/test/xml_behavior.test b/test/xml_behavior.test
new file mode 100755
index 0000000..81d8dd0
--- /dev/null
+++ b/test/xml_behavior.test
@@ -0,0 +1,2 @@
+## -*- sh -*-
+$top_builddir/test/xml_behavior_test
diff --git a/test/xml_behavior_test.c b/test/xml_behavior_test.c
new file mode 100644
index 0000000..94d8a7f
--- /dev/null
+++ b/test/xml_behavior_test.c
@@ -0,0 +1,167 @@
+/*
+ * xml_behavior_test.c
+ *
+ * Tests XML parser behavior for correctness and specification compliance:
+ *
+ * 1) A <plist> element must contain exactly one root value node.
+ * Any additional value nodes after the first root object must
+ * cause parsing to fail.
+ *
+ * 2) Dictionaries of the form:
+ * <dict>
+ * <key>CF$UID</key>
+ * <integer>...</integer>
+ * </dict>
+ * must be converted to PLIST_UID nodes during XML parsing,
+ * including when they appear nested inside other containers.
+ *
+ * These tests ensure proper root handling and UID node conversion
+ * when parsing XML property lists.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "plist/plist.h"
+
+static int test_nested_cfuid_converts_to_uid(void)
+{
+ const char *xml =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
+ "<plist version=\"1.0\">"
+ " <dict>"
+ " <key>obj</key>"
+ " <dict>"
+ " <key>CF$UID</key>"
+ " <integer>7</integer>"
+ " </dict>"
+ " </dict>"
+ "</plist>";
+
+ plist_t root = NULL;
+ plist_err_t err = plist_from_xml(xml, (uint32_t)strlen(xml), &root);
+ if (err != PLIST_ERR_SUCCESS || !root) {
+ fprintf(stderr, "nested CF$UID: plist_from_xml failed (err=%d)\n", err);
+ plist_free(root);
+ return 0;
+ }
+
+ if (plist_get_node_type(root) != PLIST_DICT) {
+ fprintf(stderr, "nested CF$UID: root is not dict\n");
+ plist_free(root);
+ return 0;
+ }
+
+ plist_t obj = plist_dict_get_item(root, "obj");
+ if (!obj) {
+ fprintf(stderr, "nested CF$UID: missing key 'obj'\n");
+ plist_free(root);
+ return 0;
+ }
+
+ if (plist_get_node_type(obj) != PLIST_UID) {
+ fprintf(stderr, "nested CF$UID: expected PLIST_UID, got %d\n",
+ plist_get_node_type(obj));
+ plist_free(root);
+ return 0;
+ }
+
+ uint64_t uid = 0;
+ plist_get_uid_val(obj, &uid);
+ if (uid != 7) {
+ fprintf(stderr, "nested CF$UID: expected uid=7, got %" PRIu64 "\n", uid);
+ plist_free(root);
+ return 0;
+ }
+
+ plist_free(root);
+ return 1;
+}
+
+static int test_extra_root_value_is_rejected(void)
+{
+ /* Two root values inside <plist> must be rejected */
+ const char *xml =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<plist version=\"1.0\">"
+ " <string>one</string>"
+ " <string>two</string>"
+ "</plist>";
+
+ plist_t root = NULL;
+ plist_err_t err = plist_from_xml(xml, (uint32_t)strlen(xml), &root);
+
+ /* Must fail, and root must be NULL (consistent with other parsers) */
+ if (err == PLIST_ERR_SUCCESS || root != NULL) {
+ fprintf(stderr, "extra root value: expected failure, got err=%d root=%p\n",
+ err, (void*)root);
+ plist_free(root);
+ return 0;
+ }
+ return 1;
+}
+
+static int test_scalar_then_extra_node_is_rejected(void)
+{
+ /* Scalar root followed by another node must be rejected */
+ const char *xml =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<plist version=\"1.0\">"
+ " <true/>"
+ " <dict><key>A</key><string>x</string></dict>"
+ "</plist>";
+
+ plist_t root = NULL;
+ plist_err_t err = plist_from_xml(xml, (uint32_t)strlen(xml), &root);
+
+ if (err == PLIST_ERR_SUCCESS || root != NULL) {
+ fprintf(stderr, "scalar then extra node: expected failure, got err=%d root=%p\n",
+ err, (void*)root);
+ plist_free(root);
+ return 0;
+ }
+ return 1;
+}
+
+static int test_scalar_with_comment_is_ok(void)
+{
+ /* Comment after the single root value is not an extra value node */
+ const char *xml =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<plist version=\"1.0\">"
+ " <string>ok</string>"
+ " <!-- trailing comment -->"
+ "</plist>";
+
+ plist_t root = NULL;
+ plist_err_t err = plist_from_xml(xml, (uint32_t)strlen(xml), &root);
+ if (err != PLIST_ERR_SUCCESS || !root) {
+ fprintf(stderr, "scalar + comment: expected success, got err=%d\n", err);
+ plist_free(root);
+ return 0;
+ }
+ if (plist_get_node_type(root) != PLIST_STRING) {
+ fprintf(stderr, "scalar + comment: expected root string, got %d\n",
+ plist_get_node_type(root));
+ plist_free(root);
+ return 0;
+ }
+ plist_free(root);
+ return 1;
+}
+
+int main(void)
+{
+ int ok = 1;
+
+ ok &= test_nested_cfuid_converts_to_uid();
+ ok &= test_extra_root_value_is_rejected();
+ ok &= test_scalar_then_extra_node_is_rejected();
+ ok &= test_scalar_with_comment_is_ok();
+
+ return ok ? 0 : 1;
+}