/ tests / lib / pkg_osvf.c
pkg_osvf.c
  1  /*-
  2   * SPDX-License-Identifier: BSD-2-Clause
  3   *
  4   *​ Copyright (c) 2025 The FreeBSD Foundation
  5   *​
  6   *​ Portions of this software were developed by
  7   * Tuukka Pasanen <tuukka.pasanen@ilmi.fi> under sponsorship from
  8   * the FreeBSD Foundation
  9   */
 10  
 11  #include <atf-c.h>
 12  #include <private/pkg_osvf.h>
 13  #include <stdlib.h>
 14  
 15  
 16  char *osvf_json_path = TESTING_TOP_DIR "/lib/FBSD-2025-05-28.json";
 17  
 18  ATF_TC_WITHOUT_HEAD(osvfdetect);
 19  ATF_TC_WITHOUT_HEAD(osvfopen);
 20  ATF_TC_WITHOUT_HEAD(osvfparse);
 21  
 22  #ifndef ATF_CHECK_INTEQ
 23  #define ATF_CHECK_INTEQ ATF_CHECK_EQ
 24  #endif
 25  
 26  ATF_TC_BODY(osvfdetect, tc)
 27  {
 28  	struct pkg_audit_ecosystem test_rtn_ecosystem_struct[] =
 29  	{
 30  		{"AlmaLinux", "AlmaLinux", NULL},
 31  		{"AlmaLinux:8", "AlmaLinux", NULL},
 32  		{"Alpine", "Alpine", NULL},
 33  		{"Alpine:v3.16", "Alpine", NULL},
 34  		{"Android", "Android", NULL},
 35  		{"Bioconductor", "Bioconductor", NULL},
 36  		{"Bitnami", "Bitnami", NULL},
 37  		{"Chainguard", "Chainguard", NULL},
 38  		{"ConanCenter", "ConanCenter", NULL},
 39  		{"CRAN", "CRAN", NULL},
 40  		{"crates.io", "crates.io", NULL},
 41  		{"Debian", "Debian", NULL},
 42  		{"Debian:13", "Debian", NULL},
 43  		{"FreeBSD", "FreeBSD", NULL},
 44  		{"FreeBSD:ports", "FreeBSD", NULL},
 45  		{"FreeBSD:src:14.3", "FreeBSD", NULL},
 46  		{"FreeBSD:kernel:14.3", "FreeBSD", NULL},
 47  		{"GHC", "GHC", NULL},
 48  		{"GitHub Actions", "GitHub Actions", NULL},
 49  		{"Go", "Go", NULL},
 50  		{"Hackage", "Hackage", NULL},
 51  		{"Hex", "Hex", NULL},
 52  		{"Kubernetes", "Kubernetes", NULL},
 53  		{"Linux", "Linux", NULL},
 54  		{"Mageia", "Mageia", NULL},
 55  		{"Mageia:9", "Mageia", NULL},
 56  		{"Maven", "Maven", NULL},
 57  		{"Maven:https://repo1.maven.org/maven2/", "Maven", NULL},
 58  		{"MinimOS", "MinimOS", NULL},
 59  		{"npm", "npm", NULL},
 60  		{"NuGet", "NuGet", NULL},
 61  		{"openSUSE", "openSUSE", NULL},
 62  		{"OSS-Fuzz", "OSS-Fuzz", NULL},
 63  		{"Packagist", "Packagist", NULL},
 64  		{"Photon OS", "Photon OS", NULL},
 65  		{"Photon OS:3.0", "Photon OS", NULL},
 66  		{"Pub", "Pub", NULL},
 67  		{"PyPI", "PyPI", NULL},
 68  		{"Red Hat", "Red Hat", NULL},
 69  		{"Red Hat:rhel_aus:8.4::appstream", "Red Hat", NULL},
 70  		{"Rocky Linux", "Rocky Linux", NULL},
 71  		{"RubyGems", "RubyGems", NULL},
 72  		{"SUSE", "SUSE", NULL},
 73  		{"SwiftURL", "SwiftURL", NULL},
 74  		{"Ubuntu", "Ubuntu", NULL},
 75  		{"Ubuntu:22.04:LTS", "Ubuntu", NULL},
 76  		{"Ubuntu:Pro:18.04:LTS", "Ubuntu", NULL},
 77  		{"Wolfi", "Wolfi", NULL},
 78  	};
 79  
 80  	unsigned int test_rtn_reference[] =
 81  	{
 82  		OSVF_REFERENCE_UNKNOWN,
 83  		OSVF_REFERENCE_ADVISORY,
 84  		OSVF_REFERENCE_ARTICLE,
 85  		OSVF_REFERENCE_DETECTION,
 86  		OSVF_REFERENCE_DISCUSSION,
 87  		OSVF_REFERENCE_REPORT,
 88  		OSVF_REFERENCE_FIX,
 89  		OSVF_REFERENCE_INTRODUCED,
 90  		OSVF_REFERENCE_PACKAGE,
 91  		OSVF_REFERENCE_EVIDENCE,
 92  		OSVF_REFERENCE_WEB
 93  	};
 94  
 95  	char *test_input_reference[] =
 96  	{
 97  		"NOTAVAIL",
 98  		"ADVISORY",
 99  		"ARTICLE",
100  		"DETECTION",
101  		"DISCUSSION",
102  		"REPORT",
103  		"FIX",
104  		"INTRODUCED",
105  		"PACKAGE",
106  		"EVIDENCE",
107  		"WEB"
108  	};
109  
110  	unsigned int test_rtn_event[] =
111  	{
112  		OSVF_EVENT_VERSION_UNKNOWN,
113  		OSVF_EVENT_VERSION_SEMVER,
114  		OSVF_EVENT_VERSION_ECOSYSTEM,
115  		OSVF_EVENT_VERSION_GIT
116  	};
117  
118  	char *test_input_event[] =
119  	{
120  		"SOMETHING",
121  		"SEMVER",
122  		"ECOSYSTEM",
123  		"GIT"
124  	};
125  
126  	int i = 0;
127  
128  
129  	for(i = 0; i < 47; i ++)
130  	{
131  		struct pkg_audit_ecosystem *ecosystem = pkg_osvf_get_ecosystem(test_rtn_ecosystem_struct[i].original);
132  
133  		ATF_REQUIRE_STREQ(ecosystem->name, test_rtn_ecosystem_struct[i].name);
134  		ATF_REQUIRE_STREQ(ecosystem->original, test_rtn_ecosystem_struct[i].original);
135  
136  		pkg_osvf_free_ecosystem(ecosystem);
137  	}
138  
139  	for(i = 0; i < 10; i ++)
140  	{
141  		ATF_REQUIRE(pkg_osvf_get_reference(test_input_reference[i]) == test_rtn_reference[i]);
142  	}
143  
144  	for(i = 0; i < 4; i ++)
145  	{
146  		ATF_REQUIRE(pkg_osvf_get_event(test_input_event[i]) == test_rtn_event[i]);
147  	}
148  
149  }
150  
151  ATF_TC_BODY(osvfopen, tc)
152  {
153  	static ucl_object_t *obj = NULL;
154  
155  	obj = pkg_osvf_open(osvf_json_path);
156  
157  	ATF_REQUIRE(obj != NULL);
158  	ucl_object_unref(obj);
159  
160  	ATF_REQUIRE(pkg_osvf_create_entry(NULL) == NULL);
161  }
162  
163  
164  ATF_TC_BODY(osvfparse, tc)
165  {
166  	static ucl_object_t *obj = NULL;
167  	char buf[1024];
168  	char *version_strs[] =
169  	{
170  		"1.0.0",
171  		"0.0.1",
172  		"1.1.0_1",
173  		"1.0.9_1",
174  		"c14e07db4",
175  		"ae637a3ad"
176  	};
177  	unsigned int version_types[] =
178  	{
179  		OSVF_EVENT_VERSION_SEMVER,
180  		OSVF_EVENT_VERSION_ECOSYSTEM,
181  		OSVF_EVENT_VERSION_GIT,
182  	};
183  	char *name_strs[] =
184  	{
185  		"osvf-test-package10",
186  		"osvf-test-package11",
187  		"osvf-test-package12"
188  	};
189  	int reference_types[] =
190  	{
191  		OSVF_REFERENCE_ADVISORY,
192  		OSVF_REFERENCE_ARTICLE,
193  		OSVF_REFERENCE_DETECTION,
194  		OSVF_REFERENCE_DISCUSSION,
195  		OSVF_REFERENCE_REPORT,
196  		OSVF_REFERENCE_FIX,
197  		OSVF_REFERENCE_INTRODUCED,
198  		OSVF_REFERENCE_PACKAGE,
199  		OSVF_REFERENCE_EVIDENCE,
200  		OSVF_REFERENCE_WEB
201  	};
202  	struct pkg_audit_versions_range *versions = NULL;
203  	struct pkg_audit_pkgname *names = NULL;
204  	struct pkg_audit_reference *references = NULL;
205  	struct pkg_audit_package *packages = NULL;
206  	int pos = 0;
207  	int subpos = 0;
208  	int otherpos = 0;
209  
210  	obj = pkg_osvf_open(osvf_json_path);
211  	ATF_REQUIRE(obj != NULL);
212  
213  	struct pkg_audit_entry *entry = pkg_osvf_create_entry(obj);
214  	ucl_object_unref(obj);
215  
216  	ATF_REQUIRE(entry != NULL);
217  
218  	ATF_CHECK_STREQ(entry->pkgname, "osvf-test-package10");
219  	ATF_CHECK_STREQ(entry->desc, "OSVF test");
220  	ATF_CHECK_STREQ(entry->url, "https://www.freebsd.org/");
221  	ATF_CHECK_STREQ(entry->id, "FBSD-2025-05-28");
222  
223  	versions = entry->versions;
224  	names = entry->names;
225  	references = entry->references;
226  	packages = entry->packages;
227  
228  	while(references)
229  	{
230  		ATF_CHECK_STREQ(references->url, "https://www.freebsd.org/");
231  		ATF_CHECK_INTEQ(references->type, reference_types[pos++]);
232  		references = references->next;
233  	}
234  
235  	pos = 0;
236  	otherpos = 0;
237  
238  	while(versions)
239  	{
240  		ATF_CHECK_INTEQ(versions->type, version_types[otherpos++]);
241  		ATF_CHECK_STREQ(versions->v2.version, version_strs[pos++]);
242  		ATF_CHECK_INTEQ(versions->v2.type, OSVF_EVENT_FIXED);
243  		ATF_CHECK_STREQ(versions->v1.version, version_strs[pos++]);
244  		ATF_CHECK_INTEQ(versions->v1.type, OSVF_EVENT_INTRODUCED);
245  		versions = versions->next;
246  	}
247  
248  	pos = 0;
249  
250  	while(names)
251  	{
252  		ATF_CHECK_STREQ(names->pkgname, name_strs[pos++]);
253  		names = names->next;
254  	}
255  
256  	pos = 0;
257  	subpos = 0;
258  	otherpos = 0;
259  
260  	while(packages)
261  	{
262  		ATF_CHECK_STREQ(packages->ecosystem->name, "FreeBSD");
263  		ATF_CHECK_STREQ(packages->names->pkgname, name_strs[pos++]);
264  
265  		versions = packages->versions;
266  
267  		while(versions)
268  		{
269  			ATF_CHECK_INTEQ(versions->type, version_types[otherpos++]);
270  			ATF_CHECK_STREQ(versions->v2.version, version_strs[subpos++]);
271  			ATF_CHECK_INTEQ(versions->v2.type, OSVF_EVENT_FIXED);
272  			ATF_CHECK_STREQ(versions->v1.version, version_strs[subpos++]);
273  			ATF_CHECK_INTEQ(versions->v1.type, OSVF_EVENT_INTRODUCED);
274  			versions = versions->next;
275  		}
276  
277  		packages = packages->next;
278  	}
279  
280  	strftime(buf, 1024, "%Y-%m-%dT%H:%M:%SZ", &entry->modified);
281  	ATF_CHECK_STREQ(buf, "2025-05-26T12:30:00Z");
282  
283  	strftime(buf, 1024, "%Y-%m-%dT%H:%M:%SZ", &entry->published);
284  	ATF_CHECK_STREQ(buf, "2025-09-28T16:00:00Z");
285  
286  	strftime(buf, 1024, "%Y-%m-%dT%H:%M:%SZ", &entry->discovery);
287  	ATF_CHECK_STREQ(buf, "2025-05-20T09:10:00Z");
288  
289  	pkg_osvf_free_entry(entry);
290  
291  }
292  
293  ATF_TP_ADD_TCS(tp)
294  {
295  	ATF_TP_ADD_TC(tp, osvfdetect);
296  	ATF_TP_ADD_TC(tp, osvfopen);
297  	ATF_TP_ADD_TC(tp, osvfparse);
298  
299  	return (atf_no_error());
300  }