Merge lp:~ted/ubuntu-app-launch/uri-splitting into lp:ubuntu-app-launch/14.04

Proposed by Ted Gould
Status: Merged
Approved by: Charles Kerr
Approved revision: 92
Merged at revision: 86
Proposed branch: lp:~ted/ubuntu-app-launch/uri-splitting
Merge into: lp:ubuntu-app-launch/14.04
Diff against target: 387 lines (+94/-152)
2 files modified
helpers.c (+75/-127)
tests/helper-test.cc (+19/-25)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/uri-splitting
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+196316@code.launchpad.net

Commit message

Ensure quoted single URIs passed to a %U are unquoted

Description of the change

Fixes the problem (see test) but also takes the time to ensure that all URIs are separate arguments and fixes the tests in response to that. Overall this makes us cleaner and gets rid of some crufty code.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'helpers.c'
--- helpers.c 2013-11-18 21:20:41 +0000
+++ helpers.c 2013-11-22 16:42:53 +0000
@@ -273,121 +273,61 @@
273 return retval;273 return retval;
274}274}
275275
276/* free a string in an array */276/* Put the list of files into the argument array */
277static inline void
278file_list_handling (GArray * outarray, gchar ** list, gchar * (*dup_func) (const gchar * in))
279{
280 /* No URLs, cool, this is a noop */
281 if (list == NULL || list[0] == NULL) {
282 return;
283 }
284
285 int i;
286 for (i = 0; list[i] != NULL; i++) {
287 gchar * entry = dup_func(list[i]);
288
289 /* No NULLs */
290 if (entry != NULL && entry[0] != '\0') {
291 g_array_append_val(outarray, entry);
292 } else {
293 g_free(entry);
294 }
295 }
296}
297
298/* Parse a desktop exec line and return the next string */
277static void299static void
278free_string (gpointer value)300desktop_exec_segment_parse (GArray * finalarray, const gchar * execsegment, gchar ** uri_list)
279{301{
280 gchar ** str = (gchar **)value;302 /* No NULL strings */
281 g_free(*str);303 if (execsegment == NULL || execsegment[0] == '\0')
282 return;304 return;
283}305
284306 /* Handle %F and %U as an argument on their own as per the spec */
285/* Builds the file list from the URI list */307 if (g_strcmp0(execsegment, "%U") == 0) {
286static gchar *308 return file_list_handling(finalarray, uri_list, g_strdup);
287build_file_list (const gchar * uri_list)309 }
288{310 if (g_strcmp0(execsegment, "%F") == 0) {
289 gchar ** uri_split = NULL;311 return file_list_handling(finalarray, uri_list, uri2file);
290 if (!g_shell_parse_argv(uri_list, NULL, &uri_split, NULL)) {312 }
291 return g_strdup("");313
292 }314 /* Start looking at individual codes */
293315 gchar ** execsplit = g_strsplit(execsegment, "%", 0);
294 GArray * outarray = g_array_new(TRUE, FALSE, sizeof(gchar *));
295 g_array_set_clear_func(outarray, free_string);
296
297 int i;
298 for (i = 0; uri_split[i] != NULL; i++) {
299 gchar * path = uri2file(uri_split[i]);
300 g_array_append_val(outarray, path);
301 }
302
303 gchar * filelist = g_strjoinv(" ", (gchar **)outarray->data);
304 g_array_free(outarray, TRUE);
305
306 g_strfreev(uri_split);
307
308 return filelist;
309}
310
311/* Make sure we have the single URI variable */
312static inline void
313ensure_singleuri (gchar ** single_uri, const gchar * uri_list)
314{
315 if (uri_list == NULL) {
316 return;
317 }
318
319 if (*single_uri != NULL) {
320 return;
321 }
322
323 gchar ** uri_split = NULL;
324 if (!g_shell_parse_argv(uri_list, NULL, &uri_split, NULL)) {
325 return;
326 }
327
328 if (uri_split[0] != NULL) {
329 *single_uri = g_strdup(uri_split[0]);
330 }
331
332 g_strfreev(uri_split);
333
334 return;
335}
336
337/* Make sure we have a single file variable */
338static inline void
339ensure_singlefile (gchar ** single_file, const gchar * uri_list)
340{
341 if (uri_list == NULL) {
342 return;
343 }
344
345 if (*single_file != NULL) {
346 return;
347 }
348
349 gchar ** uri_split = NULL;
350 if (!g_shell_parse_argv(uri_list, NULL, &uri_split, NULL)) {
351 return;
352 }
353
354 gchar * first_file = NULL;
355 if (uri_split[0] != NULL) {
356 first_file = uri2file(uri_split[0]);
357 }
358
359 g_strfreev(uri_split);
360
361 if (first_file != NULL) {
362 *single_file = first_file;
363 }
364
365 return;
366}
367
368/* Parse a desktop exec line and return the next string */
369static gchar *
370desktop_exec_segment_parse (const gchar * execline, const gchar * uri_list)
371{
372 gchar ** execsplit = g_strsplit(execline, "%", 0);
373316
374 /* If we didn't have any codes, just exit here */317 /* If we didn't have any codes, just exit here */
375 if (execsplit[1] == NULL) {318 if (execsplit[1] == NULL) {
376 g_strfreev(execsplit);319 g_strfreev(execsplit);
377 return g_strdup(execline);320 gchar * dup = g_strdup(execsegment);
378 }321 g_array_append_val(finalarray, dup);
379322 return;
380 if (uri_list != NULL && uri_list[0] == '\0') {
381 uri_list = NULL;
382 }323 }
383324
384 int i;325 int i;
385 gchar * single_uri = NULL;326
386 gchar * single_file = NULL;
387 gchar * file_list = NULL;
388 gboolean previous_percent = FALSE;327 gboolean previous_percent = FALSE;
389 GArray * outarray = g_array_new(TRUE, FALSE, sizeof(const gchar *));328 GArray * outarray = g_array_new(TRUE, FALSE, sizeof(const gchar *));
390 g_array_append_val(outarray, execsplit[0]);329 g_array_append_val(outarray, execsplit[0]);
330 gchar * single_file = NULL;
391331
392 /* The variables allowed in an exec line from the Freedesktop.org Desktop332 /* The variables allowed in an exec line from the Freedesktop.org Desktop
393 File specification: http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables */333 File specification: http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables */
@@ -418,22 +358,16 @@
418 g_array_append_val(outarray, skipchar);358 g_array_append_val(outarray, skipchar);
419 break;359 break;
420 case 'f':360 case 'f':
421 ensure_singlefile(&single_file, uri_list);361 if (uri_list != NULL && uri_list[0] != NULL) {
422362 if (single_file == NULL)
423 if (single_file != NULL) {363 single_file = uri2file(uri_list[0]);
424 g_array_append_val(outarray, single_file);364 g_array_append_val(outarray, single_file);
425 }365 }
426366
427 g_array_append_val(outarray, skipchar);367 g_array_append_val(outarray, skipchar);
428 break;368 break;
429 case 'F':369 case 'F':
430 if (uri_list != NULL) {370 g_warning("Exec line segment has a '%%F' that isn't its own argument '%s', ignoring.", execsegment);
431 if (file_list == NULL) {
432 file_list = build_file_list(uri_list);
433 }
434 g_array_append_val(outarray, file_list);
435 }
436
437 g_array_append_val(outarray, skipchar);371 g_array_append_val(outarray, skipchar);
438 break;372 break;
439 case 'i':373 case 'i':
@@ -443,16 +377,12 @@
443 g_array_append_val(outarray, skipchar);377 g_array_append_val(outarray, skipchar);
444 break;378 break;
445 case 'U':379 case 'U':
446 if (uri_list != NULL) {380 g_warning("Exec line segment has a '%%U' that isn't its own argument '%s', ignoring.", execsegment);
447 g_array_append_val(outarray, uri_list);
448 }
449 g_array_append_val(outarray, skipchar);381 g_array_append_val(outarray, skipchar);
450 break;382 break;
451 case 'u':383 case 'u':
452 ensure_singleuri(&single_uri, uri_list);384 if (uri_list != NULL && uri_list[0] != NULL) {
453385 g_array_append_val(outarray, uri_list[0]);
454 if (single_uri != NULL) {
455 g_array_append_val(outarray, single_uri);
456 }386 }
457387
458 g_array_append_val(outarray, skipchar);388 g_array_append_val(outarray, skipchar);
@@ -467,12 +397,14 @@
467 gchar * output = g_strjoinv(NULL, (gchar **)outarray->data);397 gchar * output = g_strjoinv(NULL, (gchar **)outarray->data);
468 g_array_free(outarray, TRUE);398 g_array_free(outarray, TRUE);
469399
470 g_free(single_uri);400 if (output != NULL && output[0] != '\0') {
401 g_array_append_val(finalarray, output);
402 } else {
403 g_free(output);
404 }
405
471 g_free(single_file);406 g_free(single_file);
472 g_free(file_list);
473 g_strfreev(execsplit);407 g_strfreev(execsplit);
474
475 return output;
476}408}
477409
478/* Take a full exec line, split it out, parse the segments and return410/* Take a full exec line, split it out, parse the segments and return
@@ -482,6 +414,7 @@
482{414{
483 GError * error = NULL;415 GError * error = NULL;
484 gchar ** splitexec = NULL;416 gchar ** splitexec = NULL;
417 gchar ** splituris = NULL;
485 gint execitems = 0;418 gint execitems = 0;
486419
487 /* This returns from desktop file style quoting to straight strings with420 /* This returns from desktop file style quoting to straight strings with
@@ -496,14 +429,29 @@
496 return NULL;429 return NULL;
497 }430 }
498431
432 if (urilist != NULL && urilist[0] != '\0') {
433 g_shell_parse_argv(urilist, NULL, &splituris, &error);
434
435 if (error != NULL) {
436 g_warning("Unable to parse URIs '%s': %s", urilist, error->message);
437 g_error_free(error);
438 /* Continuing without URIs */
439 splituris = NULL;
440 }
441 }
442
443
499 GArray * newargv = g_array_new(TRUE, FALSE, sizeof(gchar *));444 GArray * newargv = g_array_new(TRUE, FALSE, sizeof(gchar *));
500 int i;445 int i;
501 for (i = 0; i < execitems; i++) {446 for (i = 0; i < execitems; i++) {
502 gchar * execinserted = desktop_exec_segment_parse(splitexec[i], urilist);447 desktop_exec_segment_parse(newargv, splitexec[i], splituris);
503 g_array_append_val(newargv, execinserted);
504 }448 }
505 g_strfreev(splitexec);449 g_strfreev(splitexec);
506450
451 if (splituris != NULL) {
452 g_strfreev(splituris);
453 }
454
507 /* Each string here should be its own param */455 /* Each string here should be its own param */
508456
509 return newargv;457 return newargv;
510458
=== modified file 'tests/helper-test.cc'
--- tests/helper-test.cc 2013-11-18 21:20:41 +0000
+++ tests/helper-test.cc 2013-11-22 16:42:53 +0000
@@ -84,9 +84,8 @@
8484
85 /* Little u with a NULL string */85 /* Little u with a NULL string */
86 output = desktop_exec_parse("foo %u", "");86 output = desktop_exec_parse("foo %u", "");
87 ASSERT_EQ(output->len, 2);87 ASSERT_EQ(output->len, 1);
88 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");88 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
89 ASSERT_STREQ(g_array_index(output, gchar *, 1), "");
90 g_array_free(output, TRUE);89 g_array_free(output, TRUE);
9190
92 /* Big %U with a single URL */91 /* Big %U with a single URL */
@@ -121,9 +120,8 @@
121120
122 /* URL is a quote, make sure we handle the error */121 /* URL is a quote, make sure we handle the error */
123 output = desktop_exec_parse("foo %u", "\"");122 output = desktop_exec_parse("foo %u", "\"");
124 ASSERT_EQ(output->len, 2);123 ASSERT_EQ(output->len, 1);
125 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");124 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
126 ASSERT_STREQ(g_array_index(output, gchar *, 1), "");
127 g_array_free(output, TRUE);125 g_array_free(output, TRUE);
128126
129 /* Lots of quotes, escaped and not */127 /* Lots of quotes, escaped and not */
@@ -141,16 +139,23 @@
141139
142 /* Big U with two URLs */140 /* Big U with two URLs */
143 output = desktop_exec_parse("foo %U", "http://ubuntu.com http://slashdot.org");141 output = desktop_exec_parse("foo %U", "http://ubuntu.com http://slashdot.org");
144 ASSERT_EQ(output->len, 2);142 ASSERT_EQ(output->len, 3);
145 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");143 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
146 ASSERT_STREQ(g_array_index(output, gchar *, 1), "http://ubuntu.com http://slashdot.org");144 ASSERT_STREQ(g_array_index(output, gchar *, 1), "http://ubuntu.com");
145 ASSERT_STREQ(g_array_index(output, gchar *, 2), "http://slashdot.org");
147 g_array_free(output, TRUE);146 g_array_free(output, TRUE);
148147
149 /* Big U with no URLs */148 /* Big U with no URLs */
150 output = desktop_exec_parse("foo %U", NULL);149 output = desktop_exec_parse("foo %U", NULL);
150 ASSERT_EQ(output->len, 1);
151 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
152 g_array_free(output, TRUE);
153
154 /* Big U with quoted URL */
155 output = desktop_exec_parse("foo %U", "'http://ubuntu.com'");
151 ASSERT_EQ(output->len, 2);156 ASSERT_EQ(output->len, 2);
152 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");157 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
153 ASSERT_STREQ(g_array_index(output, gchar *, 1), "");158 ASSERT_STREQ(g_array_index(output, gchar *, 1), "http://ubuntu.com");
154 g_array_free(output, TRUE);159 g_array_free(output, TRUE);
155160
156 /* Big U with URLs that have spaces */161 /* Big U with URLs that have spaces */
@@ -169,16 +174,14 @@
169174
170 /* A %f with a NULL string */175 /* A %f with a NULL string */
171 output = desktop_exec_parse("foo %f", "");176 output = desktop_exec_parse("foo %f", "");
172 ASSERT_EQ(output->len, 2);177 ASSERT_EQ(output->len, 1);
173 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");178 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
174 ASSERT_STREQ(g_array_index(output, gchar *, 1), "");
175 g_array_free(output, TRUE);179 g_array_free(output, TRUE);
176180
177 /* %f with a URL that isn't a file */181 /* %f with a URL that isn't a file */
178 output = desktop_exec_parse("foo %f", "torrent://moviephone.com/hot-new-movie");182 output = desktop_exec_parse("foo %f", "torrent://moviephone.com/hot-new-movie");
179 ASSERT_EQ(output->len, 2);183 ASSERT_EQ(output->len, 1);
180 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");184 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
181 ASSERT_STREQ(g_array_index(output, gchar *, 1), "");
182 g_array_free(output, TRUE);185 g_array_free(output, TRUE);
183186
184 /* Lots of %f combinations */187 /* Lots of %f combinations */
@@ -200,16 +203,16 @@
200203
201 /* Big F with two files */204 /* Big F with two files */
202 output = desktop_exec_parse("foo %F", "file:///proc/version file:///proc/uptime");205 output = desktop_exec_parse("foo %F", "file:///proc/version file:///proc/uptime");
203 ASSERT_EQ(output->len, 2);206 ASSERT_EQ(output->len, 3);
204 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");207 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
205 ASSERT_STREQ(g_array_index(output, gchar *, 1), "/proc/version /proc/uptime");208 ASSERT_STREQ(g_array_index(output, gchar *, 1), "/proc/version");
209 ASSERT_STREQ(g_array_index(output, gchar *, 2), "/proc/uptime");
206 g_array_free(output, TRUE);210 g_array_free(output, TRUE);
207211
208 /* Big F with no files */212 /* Big F with no files */
209 output = desktop_exec_parse("foo %F", NULL);213 output = desktop_exec_parse("foo %F", NULL);
210 ASSERT_EQ(output->len, 2);214 ASSERT_EQ(output->len, 1);
211 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");215 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
212 ASSERT_STREQ(g_array_index(output, gchar *, 1), "");
213 g_array_free(output, TRUE);216 g_array_free(output, TRUE);
214217
215 /* Groups of percents */218 /* Groups of percents */
@@ -223,17 +226,8 @@
223226
224 /* All the % sequences we don't support */227 /* All the % sequences we don't support */
225 output = desktop_exec_parse("foo %d %D %n %N %v %m %i %c %k", "file:///proc/version");228 output = desktop_exec_parse("foo %d %D %n %N %v %m %i %c %k", "file:///proc/version");
226 ASSERT_EQ(output->len, 10);229 ASSERT_EQ(output->len, 1);
227 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");230 ASSERT_STREQ(g_array_index(output, gchar *, 0), "foo");
228 ASSERT_STREQ(g_array_index(output, gchar *, 1), "");
229 ASSERT_STREQ(g_array_index(output, gchar *, 2), "");
230 ASSERT_STREQ(g_array_index(output, gchar *, 3), "");
231 ASSERT_STREQ(g_array_index(output, gchar *, 4), "");
232 ASSERT_STREQ(g_array_index(output, gchar *, 5), "");
233 ASSERT_STREQ(g_array_index(output, gchar *, 6), "");
234 ASSERT_STREQ(g_array_index(output, gchar *, 7), "");
235 ASSERT_STREQ(g_array_index(output, gchar *, 8), "");
236 ASSERT_STREQ(g_array_index(output, gchar *, 9), "");
237 g_array_free(output, TRUE);231 g_array_free(output, TRUE);
238232
239 return;233 return;

Subscribers

People subscribed via source and target branches