tracker-0.16.2/tests/libtracker-data/tracker-ontology-test.c

Location Tool Test ID Function Issue
tracker-ontology-test.c:143:23 clang-analyzer Access to field 'str' results in a dereference of a null pointer (loaded from variable 'test_results')
  1 /*
  2  * Copyright (C) 2009, Nokia <ivan.frade@nokia.com>
  3  *
  4  * This library is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) any later version.
  8  *
  9  * This library is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU General Public
 15  * License along with this library; if not, write to the
 16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 17  * Boston, MA  02110-1301, USA.
 18  */
 19 
 20 #include "config.h"
 21 
 22 #include <string.h>
 23 #include <locale.h>
 24 
 25 #include <glib.h>
 26 #include <gio/gio.h>
 27 #include <glib/gstdio.h>
 28 
 29 #include <libtracker-data/tracker-data-manager.h>
 30 #include <libtracker-data/tracker-data-query.h>
 31 #include <libtracker-data/tracker-data-update.h>
 32 #include <libtracker-data/tracker-data.h>
 33 #include <libtracker-data/tracker-sparql-query.h>
 34 
 35 typedef struct _TestInfo TestInfo;
 36 
 37 struct _TestInfo {
 38 	const gchar *test_name;
 39 	const gchar *data;
 40 };
 41 
 42 typedef struct _ChangeInfo ChangeInfo;
 43 
 44 struct _ChangeInfo {
 45 	const gchar *ontology;
 46 	const gchar *update;
 47 	const gchar *test_name;
 48 	const gchar *ptr;
 49 };
 50 
 51 const TestInfo nie_tests[] = {
 52 	{ "nie/filter-subject-1", "nie/data-1" },
 53 	{ "nie/filter-characterset-1", "nie/data-1" },
 54 	{ "nie/filter-comment-1", "nie/data-1" },
 55 	{ "nie/filter-description-1", "nie/data-1" },
 56 	{ "nie/filter-generator-1", "nie/data-1" },
 57 	{ "nie/filter-identifier-1", "nie/data-1" },
 58 	{ "nie/filter-keyword-1", "nie/data-1" },
 59 	{ "nie/filter-language-1", "nie/data-1" },
 60 	{ "nie/filter-legal-1", "nie/data-1" },
 61 	{ "nie/filter-title-1", "nie/data-1" },
 62 	{ "nie/filter-version-1", "nie/data-1" },
 63 	{ NULL }
 64 };
 65 
 66 const TestInfo nmo_tests[] = {
 67 	{ "nmo/filter-charset-1", "nmo/data-1" },
 68 	{ "nmo/filter-contentdescription-1", "nmo/data-1" },
 69 	{ "nmo/filter-contentid-1", "nmo/data-1" },
 70 	{ "nmo/filter-contenttransferencoding-1", "nmo/data-1" },
 71 	{ "nmo/filter-headername-1", "nmo/data-1" },
 72 	{ "nmo/filter-headervalue-1", "nmo/data-1" },
 73 	{ "nmo/filter-isanswered-1", "nmo/data-1" },
 74 	{ "nmo/filter-isdeleted-1", "nmo/data-1" },
 75 	{ "nmo/filter-isdraft-1", "nmo/data-1" },
 76 	{ "nmo/filter-isflagged-1", "nmo/data-1" },
 77 	{ "nmo/filter-isread-1", "nmo/data-1" },
 78 	{ "nmo/filter-isrecent-1", "nmo/data-1" },
 79 	{ "nmo/filter-messageid-1", "nmo/data-1" },
 80 	{ "nmo/filter-messagesubject-1", "nmo/data-1" },
 81 	{ NULL }
 82 };
 83 
 84 static void
 85 query_helper (const gchar *query_filename, const gchar *results_filename)
 86 {
 87 	GError *error = NULL;
 88 	gchar *queries = NULL, *query;
 89 	gchar *results = NULL;
 90 	GString *test_results = NULL;
 91 
 92 	g_file_get_contents (query_filename, &queries, NULL, &error);
 93 	g_assert_no_error (error);
 94 
 95 	g_file_get_contents (results_filename, &results, NULL, &error);
 96 	g_assert_no_error (error);
 97 
 98 	/* perform actual query */
 99 
100 	query = strtok (queries, "~");
101 
102 	while (query) {
103 		TrackerDBCursor *cursor;
104 
105 		cursor = tracker_data_query_sparql_cursor (query, &error);
106 		g_assert_no_error (error);
107 
108 		/* compare results with reference output */
109 
110 		if (!test_results) {
111 			test_results = g_string_new ("");
112 		} else {
113 			g_string_append (test_results, "~\n");
114 		}
115 
116 		if (cursor) {
117 			gint col;
118 
119 			while (tracker_db_cursor_iter_next (cursor, NULL, &error)) {
120 				for (col = 0; col < tracker_db_cursor_get_n_columns (cursor); col++) {
121 					const gchar *str;
122 
123 					if (col > 0) {
124 						g_string_append (test_results, "\t");
125 					}
126 
127 					str = tracker_db_cursor_get_string (cursor, col, NULL);
128 					if (str != NULL) {
129 						/* bound variable */
130 						g_string_append_printf (test_results, "\"%s\"", str);
131 					}
132 				}
133 
134 				g_string_append (test_results, "\n");
135 			}
136 
137 			g_object_unref (cursor);
138 		}
139 
140 		query = strtok (NULL, "~");
141 	}
142 
143 	if (strcmp (results, test_results->str)) {
Access to field 'str' results in a dereference of a null pointer (loaded from variable 'test_results')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

144 /* print result difference */ 145 gchar *quoted_results; 146 gchar *command_line; 147 gchar *quoted_command_line; 148 gchar *shell; 149 gchar *diff; 150 151 quoted_results = g_shell_quote (test_results->str); 152 command_line = g_strdup_printf ("echo -n %s | diff -u %s -", quoted_results, results_filename); 153 quoted_command_line = g_shell_quote (command_line); 154 shell = g_strdup_printf ("sh -c %s", quoted_command_line); 155 g_spawn_command_line_sync (shell, &diff, NULL, NULL, &error); 156 g_assert_no_error (error); 157 158 g_error ("%s", diff); 159 160 g_free (quoted_results); 161 g_free (command_line); 162 g_free (quoted_command_line); 163 g_free (shell); 164 g_free (diff); 165 } 166 167 g_string_free (test_results, TRUE); 168 g_free (results); 169 g_free (queries); 170 } 171 172 static void 173 test_ontology_init (void) 174 { 175 GError *error = NULL; 176 177 tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL); 178 179 /* first-time initialization */ 180 tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX, 181 NULL, 182 NULL, 183 FALSE, 184 FALSE, 185 100, 186 100, 187 NULL, 188 NULL, 189 NULL, 190 &error); 191 192 g_assert_no_error (error); 193 194 tracker_data_manager_shutdown (); 195 196 tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL); 197 198 /* initialization from existing database */ 199 tracker_data_manager_init (0, 200 NULL, 201 NULL, 202 FALSE, 203 FALSE, 204 100, 205 100, 206 NULL, 207 NULL, 208 NULL, 209 &error); 210 211 g_assert_no_error (error); 212 213 tracker_data_manager_shutdown (); 214 } 215 216 static void 217 test_query (gconstpointer test_data) 218 { 219 const TestInfo *test_info; 220 GError *error; 221 gchar *data_filename; 222 gchar *query_filename; 223 gchar *results_filename; 224 gchar *prefix, *data_prefix, *test_prefix; 225 226 error = NULL; 227 test_info = test_data; 228 229 prefix = g_build_path (G_DIR_SEPARATOR_S, TOP_SRCDIR, "tests", "libtracker-data", NULL); 230 231 data_prefix = g_build_filename (prefix, test_info->data, NULL); 232 test_prefix = g_build_filename (prefix, test_info->test_name, NULL); 233 g_free (prefix); 234 235 tracker_db_journal_set_rotating (FALSE, G_MAXSIZE, NULL); 236 237 /* initialization */ 238 tracker_data_manager_init (TRACKER_DB_MANAGER_FORCE_REINDEX, 239 NULL, 240 NULL, 241 FALSE, 242 FALSE, 243 100, 244 100, 245 NULL, 246 NULL, 247 NULL, 248 NULL); 249 250 /* load data set */ 251 data_filename = g_strconcat (data_prefix, ".ttl", NULL); 252 tracker_turtle_reader_load (data_filename, &error); 253 g_assert_no_error (error); 254 255 query_filename = g_strconcat (test_prefix, ".rq", NULL); 256 results_filename = g_strconcat (test_prefix, ".out", NULL); 257 258 g_free (data_prefix); 259 g_free (test_prefix); 260 261 query_helper (query_filename, results_filename); 262 263 /* cleanup */ 264 265 g_free (data_filename); 266 g_free (query_filename); 267 g_free (results_filename); 268 269 tracker_data_manager_shutdown (); 270 } 271 272 int 273 main (int argc, char **argv) 274 { 275 gint result; 276 gint i; 277 gchar *data_dir; 278 279 g_test_init (&argc, &argv, NULL); 280 281 data_dir = g_build_filename (g_get_current_dir (), "test-cache", NULL); 282 283 /* Warning warning!!! We need to impose a proper LC_COLLATE here, so 284 * that the expected order in the test results is always the same! */ 285 setlocale (LC_COLLATE, "en_US.utf8"); 286 287 g_setenv ("XDG_DATA_HOME", data_dir, TRUE); 288 g_setenv ("XDG_CACHE_HOME", data_dir, TRUE); 289 g_setenv ("TRACKER_DB_ONTOLOGIES_DIR", TOP_SRCDIR "/data/ontologies/", TRUE); 290 291 /* add test cases */ 292 293 g_test_add_func ("/libtracker-data/ontology-init", test_ontology_init); 294 295 for (i = 0; nie_tests[i].test_name; i++) { 296 gchar *testpath; 297 298 g_message ("%d", i); 299 300 testpath = g_strconcat ("/libtracker-data/nie/", nie_tests[i].test_name, NULL); 301 g_test_add_data_func (testpath, &nie_tests[i], test_query); 302 g_free (testpath); 303 } 304 305 for (i = 0; nmo_tests[i].test_name; i++) { 306 gchar *testpath; 307 308 g_message ("%d", i); 309 310 testpath = g_strconcat ("/libtracker-data/nmo/", nmo_tests[i].test_name, NULL); 311 g_test_add_data_func (testpath, &nmo_tests[i], test_query); 312 g_free (testpath); 313 } 314 315 /* run tests */ 316 317 result = g_test_run (); 318 319 /* clean up */ 320 g_print ("Removing temporary data\n"); 321 g_spawn_command_line_sync ("rm -R tracker/", NULL, NULL, NULL, NULL); 322 g_spawn_command_line_sync ("rm -R test-cache/", NULL, NULL, NULL, NULL); 323 324 g_free (data_dir); 325 326 return result; 327 }