Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : *
3 : : * Copyright 2025 GNOME Foundation, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General Public
18 : : * License along with this library; if not, write to the Free Software
19 : : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 : : *
21 : : * Authors:
22 : : * - Philip Withnall <pwithnall@gnome.org>
23 : : */
24 : :
25 : : #include "config.h"
26 : :
27 : : #include <glib.h>
28 : : #include <libmalcontent-web/filter-list.h>
29 : : #include <locale.h>
30 : :
31 : :
32 : : static gboolean
33 : 10 : parse_cb (const char *hostname,
34 : : size_t hostname_len,
35 : : void *user_data,
36 : : GError **error)
37 : : {
38 : 10 : GList **hostnames_out = user_data;
39 : :
40 : 10 : *hostnames_out = g_list_prepend (*hostnames_out, g_strndup (hostname, hostname_len));
41 : :
42 : 10 : return TRUE;
43 : : }
44 : :
45 : : static void
46 : 1 : test_filter_list_parsing (void)
47 : : {
48 : : const struct
49 : : {
50 : : const char *data;
51 : : size_t data_len; /* might not just be strlen(data) if we want to test length handling */
52 : : gboolean expected_success;
53 : : const char *expected_hostnames[10]; /* (array zero-terminated=1) */
54 : : }
55 : 1 : vectors[] =
56 : : {
57 : : { "", 0, TRUE, { NULL, } },
58 : : { " ", 0, TRUE, { NULL, } },
59 : : { "# just a comment", 0, TRUE, { NULL, } },
60 : : { "# just a comment\n", 0, TRUE, { NULL, } },
61 : : { " # just a comment", 0, TRUE, { NULL, } },
62 : : { "example.com", 0, TRUE, { "example.com", NULL, } },
63 : : { "example.com\n", 0, TRUE, { "example.com", NULL, } },
64 : : { "example.com\n\n\n", 0, TRUE, { "example.com", NULL, } },
65 : : { " example.com\n", 0, TRUE, { "example.com", NULL, } },
66 : : { " example.com \n", 0, TRUE, { "example.com", NULL, } },
67 : : { "example.com \n ", 0, TRUE, { "example.com", NULL, } },
68 : : { "example.com\ntest.com", 0, TRUE, { "example.com", "test.com", NULL, } },
69 : : { "example.com\n# one comment\n # another comment\ntest.com", 0, TRUE, { "example.com", "test.com", NULL, } },
70 : : };
71 : :
72 [ + + ]: 14 : for (size_t i = 0; i < G_N_ELEMENTS (vectors); i++)
73 : : {
74 : : gboolean success;
75 : 13 : g_autoptr(GError) local_error = NULL;
76 : 13 : GList *hostnames = NULL;
77 : :
78 : 13 : success = mct_filter_list_parse_from_data (vectors[i].data,
79 [ - + ]: 13 : (vectors[i].data_len != 0) ? vectors[i].data_len : strlen (vectors[i].data),
80 : : parse_cb,
81 : : &hostnames,
82 : : &local_error);
83 : 13 : hostnames = g_list_reverse (hostnames); /* because we use g_list_prepend() above */
84 : :
85 [ + - ]: 13 : if (vectors[i].expected_success)
86 : : {
87 : 13 : size_t j = 0;
88 : :
89 : 13 : g_assert_true (success);
90 : 13 : g_assert_no_error (local_error);
91 : :
92 : 13 : g_assert_cmpuint (g_list_length (hostnames), ==, g_strv_length ((char **) vectors[i].expected_hostnames));
93 : :
94 [ + + ]: 23 : for (GList *l = hostnames; l != NULL; l = l->next, j++)
95 : : {
96 : 10 : const char *expected_hostname = vectors[i].expected_hostnames[j];
97 : 10 : const char *hostname = (const char *) l->data;
98 : :
99 : 10 : g_assert_cmpstr (hostname, ==, expected_hostname);
100 : : }
101 : : }
102 : : else
103 : : {
104 : : /* We don’t need to check the exact error which has been set, because
105 : : * it’s only set in parse_cb(), which is part of the test harness. */
106 : 0 : g_assert_false (success);
107 : 0 : g_assert_nonnull (local_error);
108 : 0 : g_assert_null (hostnames);
109 : : }
110 : :
111 : 13 : g_list_free_full (hostnames, g_free);
112 : : }
113 : 1 : }
114 : :
115 : : static gboolean
116 : 1 : parse_error_cb (const char *hostname,
117 : : size_t hostname_len,
118 : : void *user_data,
119 : : GError **error)
120 : : {
121 : 1 : g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "oh no");
122 : :
123 : 1 : return FALSE;
124 : : }
125 : :
126 : : static void
127 : 1 : test_filter_list_parsing_reject_hostname (void)
128 : : {
129 : : gboolean success;
130 : 1 : g_autoptr(GError) local_error = NULL;
131 : :
132 : 1 : success = mct_filter_list_parse_from_data ("example.com",
133 : : strlen ("example.com"),
134 : : parse_error_cb,
135 : : NULL,
136 : : &local_error);
137 : :
138 : : /* We don’t need to check the exact error which has been set, because
139 : : * it’s only set in parse_cb(), which is part of the test harness. */
140 : 1 : g_assert_false (success);
141 : 1 : g_assert_nonnull (local_error);
142 : 1 : }
143 : :
144 : : int
145 : 1 : main (int argc,
146 : : char **argv)
147 : : {
148 : 1 : setlocale (LC_ALL, "");
149 : 1 : g_test_init (&argc, &argv, NULL);
150 : :
151 : 1 : g_test_add_func ("/filter-list/parsing", test_filter_list_parsing);
152 : 1 : g_test_add_func ("/filter-list/parsing/reject-hostname", test_filter_list_parsing_reject_hostname);
153 : :
154 : 1 : return g_test_run ();
155 : : }
|