1 /*
2 * test-oom.c
3 * Allocation-failure (OOM) tests for spdxtool, using the oom.h injection
4 * harness. For each target, a failure is injected at every successive
5 * allocation; the target must report the error gracefully (NULL) and, under
6 * ASAN, leak nothing on the error path.
7 *
8 * SPDX-License-Identifier: pkgconf
9 *
10 * Copyright (c) 2026 pkgconf authors (see AUTHORS).
11 *
12 * Permission to use, copy, modify, and/or distribute this software for any
13 * purpose with or without fee is hereby granted, provided that the above
14 * copyright notice and this permission notice appear in all copies.
15 *
16 * This software is provided 'as is' and without any warranty, express or
17 * implied. In no event shall the authors be liable for any damages arising
18 * from the use of this software.
19 */
20
21 #include <libpkgconf/stdinc.h>
22 #include <libpkgconf/libpkgconf.h>
23 #include "oom.h"
24 #include "core.h"
25 #include "software.h"
26 #include "simplelicensing.h"
27 #include "serialize.h"
28 #include "util.h"
29
30 static pkgconf_client_t *g_client;
31
32 static void
oom_setup(void)33 oom_setup(void)
34 {
35 g_client = test_client_new();
36 // Mirror cli/spdxtool/main.c: the constructors read these globals
37 spdxtool_util_set_uri_root(g_client, "https://example.com/test");
38 spdxtool_util_set_uri_separator_colon(g_client, false);
39 spdxtool_util_set_spdx_version(g_client, "3.0.1");
40 spdxtool_util_set_spdx_license(g_client, "CC0-1.0");
41 }
42
43 /*
44 * ==============================================
45 * core / software / simplelicensing constructors
46 * ==============================================
47 */
48
49 static void
test_oom_agent_new(void)50 test_oom_agent_new(void)
51 {
52 spdxtool_core_agent_t *a;
53 OOM_TEST_PTR(a, spdxtool_core_agent_new(g_client, "_:c1", "Agent Name"), spdxtool_core_agent_free(a));
54 }
55
56 static void
test_oom_creation_info_new(void)57 test_oom_creation_info_new(void)
58 {
59 spdxtool_core_creation_info_t *c;
60 // NULL time exercises the get_current_iso8601_time() strdup path too
61 OOM_TEST_PTR(c, spdxtool_core_creation_info_new(g_client, "agentid", "_:c1", NULL),
62 spdxtool_core_creation_info_free(c));
63 }
64
65 static void
test_oom_spdx_document_new(void)66 test_oom_spdx_document_new(void)
67 {
68 spdxtool_core_spdx_document_t *d;
69 OOM_TEST_PTR(d, spdxtool_core_spdx_document_new(g_client, "docid", "_:c1", "agentid"),
70 spdxtool_core_spdx_document_free(d));
71 }
72
73 static void
test_oom_sbom_new(void)74 test_oom_sbom_new(void)
75 {
76 spdxtool_software_sbom_t *s;
77 OOM_TEST_PTR(s, spdxtool_software_sbom_new(g_client, "sbomid", "_:c1", "build"), spdxtool_software_sbom_free(s));
78 }
79
80 static void
test_oom_license_expression_new(void)81 test_oom_license_expression_new(void)
82 {
83 spdxtool_simplelicensing_license_expression_t *e;
84 OOM_TEST_PTR(e, spdxtool_simplelicensing_licenseExpression_new(g_client, "MIT"),
85 spdxtool_simplelicensing_licenseExpression_free(e));
86 }
87
88 /*
89 * ======================
90 * serializer value model
91 * ======================
92 */
93
94 static void
test_oom_serialize_constructors(void)95 test_oom_serialize_constructors(void)
96 {
97 spdxtool_serialize_object_list_t *o;
98 OOM_TEST_PTR(o, spdxtool_serialize_object_list_new(), spdxtool_serialize_object_list_free(o));
99
100 spdxtool_serialize_array_t *a;
101 OOM_TEST_PTR(a, spdxtool_serialize_array_new(), spdxtool_serialize_array_free(a));
102
103 spdxtool_serialize_value_t *v;
104 OOM_TEST_PTR(v, spdxtool_serialize_value_string("hello"), spdxtool_serialize_value_free(v));
105 OOM_TEST_PTR(v, spdxtool_serialize_value_int(7), spdxtool_serialize_value_free(v));
106 OOM_TEST_PTR(v, spdxtool_serialize_value_bool(true), spdxtool_serialize_value_free(v));
107 OOM_TEST_PTR(v, spdxtool_serialize_value_null(), spdxtool_serialize_value_free(v));
108 }
109
110 /*
111 * ============================================================
112 * *_to_object serializers that depend only on their own struct
113 * ============================================================
114 */
115
116 static void
test_oom_to_object(void)117 test_oom_to_object(void)
118 {
119 spdxtool_serialize_value_t *v;
120
121 spdxtool_core_agent_t *agent = spdxtool_core_agent_new(g_client, "_:c1", "Agent");
122 TEST_ASSERT_NONNULL(agent);
123 OOM_TEST_PTR(v, spdxtool_core_agent_to_object(g_client, agent),
124 spdxtool_serialize_value_free(v));
125 spdxtool_core_agent_free(agent);
126
127 spdxtool_core_creation_info_t *ci =
128 spdxtool_core_creation_info_new(g_client, "agentid", "_:c1", "2020-01-01T00:00:00Z");
129 TEST_ASSERT_NONNULL(ci);
130 OOM_TEST_PTR(v, spdxtool_core_creation_info_to_object(g_client, ci),
131 spdxtool_serialize_value_free(v));
132 spdxtool_core_creation_info_free(ci);
133
134 spdxtool_simplelicensing_license_expression_t *le =
135 spdxtool_simplelicensing_licenseExpression_new(g_client, "MIT");
136 TEST_ASSERT_NONNULL(le);
137 OOM_TEST_PTR(v, spdxtool_simplelicensing_licenseExpression_to_object(g_client, "_:c1", le),
138 spdxtool_serialize_value_free(v));
139 spdxtool_simplelicensing_licenseExpression_free(le);
140 }
141
142 int
main(int argc,const char ** argv)143 main(int argc, const char **argv)
144 {
145 (void) argc;
146 const char *basename = pkgconf_path_find_basename(argv[0]);
147
148 oom_setup();
149
150 TEST_RUN(basename, test_oom_agent_new);
151 TEST_RUN(basename, test_oom_creation_info_new);
152 TEST_RUN(basename, test_oom_spdx_document_new);
153 TEST_RUN(basename, test_oom_sbom_new);
154 TEST_RUN(basename, test_oom_license_expression_new);
155 TEST_RUN(basename, test_oom_serialize_constructors);
156 TEST_RUN(basename, test_oom_to_object);
157
158 pkgconf_client_free(g_client);
159 return EXIT_SUCCESS;
160 }
161