Make it possible to escape paths containing special shell characters

Allow paths and other components to contain shell metacharacters, but
escape them on output.  White space has to be escaped in the input
files using quotes or backslashes

Freedesktop.org #3571
This commit is contained in:
Tollef Fog Heen 2010-05-23 22:59:46 +02:00
parent 5ade770f76
commit 69a7eaa676
4 changed files with 78 additions and 51 deletions

View file

@ -1,10 +1,10 @@
TESTS = check-cflags check-libs check-define-variable \
check-libs-private check-requires-private check-includedir \
check-conflicts check-missing check-idirafter
check-conflicts check-missing check-idirafter check-whitespace
EXTRA_DIST = $(TESTS) common simple.pc requires-test.pc public-dep.pc \
private-dep.pc includedir.pc missing-requires-private.pc \
missing-requires.pc idirafter.pc
missing-requires.pc idirafter.pc whitespace.pc
DISTCLEANFILES = config.sh

20
check/check-whitespace Executable file
View file

@ -0,0 +1,20 @@
#! /bin/sh
# Make sure we're POSIX
if [ "$PKG_CONFIG_SHELL_IS_POSIX" != "1" ]; then
PKG_CONFIG_SHELL_IS_POSIX=1 PATH=`getconf PATH` exec sh $0 "$@"
fi
set -e
. ${srcdir}/common
# expect cflags from whitespace
ARGS="--cflags whitespace"
RESULT="-I/usr/white\\ space/include -Iinclude\\ dir -Iother\\ include\\ dir"
run_test
# expect libs from whitespace
ARGS="--libs whitespace"
RESULT="-L/usr/white\\ space/lib -lfoo\\ bar -lbar\\ baz"
run_test

11
check/whitespace.pc Normal file
View file

@ -0,0 +1,11 @@
prefix=/usr
exec_prefix=${prefix}
libdir="${exec_prefix}/white space/lib"
includedir="${prefix}/white space/include"
Name: Whitespace test
Description: Dummy pkgconfig test package for testing pkgconfig
Version: 1.0.0
Requires:
Libs: -L${libdir} -lfoo\ bar "-lbar baz"
Cflags: -I${includedir} -Iinclude\ dir "-Iother include dir"

94
parse.c
View file

@ -633,6 +633,31 @@ parse_conflicts (Package *pkg, const char *str, const char *path)
g_free (trimmed);
}
static char *strdup_escape_shell(const char *s)
{
size_t r_s = strlen(s)+10, c = 0;
char *r = g_malloc(r_s);
while (s[0]) {
if ((s[0] < '+') ||
(s[0] > '9' && s[0] < '@') ||
(s[0] > 'Z' && s[0] < '^') ||
(s[0] == '`') ||
(s[0] > 'z')) {
r[c] = '\\';
c++;
}
r[c] = *s;
c++;
if (c+2 >= r_s) {
r_s *= 2;
r = g_realloc(r, r_s);
}
s++;
}
r[c] = 0;
return r;
}
static void _do_parse_libs (Package *pkg, int argc, char **argv)
{
int i;
@ -649,12 +674,11 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
i = 0;
while (i < argc)
{
char *arg = trim_string (argv[i]);
char *tmp = trim_string (argv[i]);
char *arg = strdup_escape_shell(tmp);
char *p;
char *start;
start = arg;
p = start;
p = arg;
g_free(tmp);
if (p[0] == '-' &&
p[1] == 'l' &&
@ -662,43 +686,23 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
flag. */
(strncmp(p, "-lib:", 5) != 0))
{
char *libname;
p += 2;
while (*p && isspace ((guchar)*p))
++p;
start = p;
while (*p && !isspace ((guchar)*p))
++p;
libname = g_strndup (start, p - start);
pkg->l_libs = g_slist_prepend (pkg->l_libs,
g_strconcat (l_flag, libname, lib_suffix, NULL));
g_strconcat (l_flag, p, lib_suffix, NULL));
g_free (libname);
}
else if (p[0] == '-' &&
p[1] == 'L')
{
char *libname;
p += 2;
while (*p && isspace ((guchar)*p))
++p;
start = p;
while (*p && !isspace ((guchar)*p))
++p;
libname = g_strndup (start, p - start);
pkg->L_libs = g_slist_prepend (pkg->L_libs,
g_strconcat (L_flag, libname, NULL));
g_free (libname);
}
pkg->L_libs = g_slist_prepend (pkg->L_libs,
g_strconcat (L_flag, p, NULL));
}
else if (strcmp("-framework",p) == 0 && i+1 < argc)
{
/* Mac OS X has a -framework Foo which is really one option,
@ -706,12 +710,14 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
* -framework Bar being changed into -framework Foo Bar
* later
*/
gchar *framework = trim_string (argv[i+1]);
gchar *framework, *tmp = trim_string (argv[i+1]);
framework = strdup_escape_shell(tmp);
pkg->other_libs = g_slist_prepend (pkg->other_libs,
g_strconcat(arg, " ", framework, NULL));
i++;
g_free(framework);
g_free(tmp);
}
else
{
@ -721,7 +727,7 @@ static void _do_parse_libs (Package *pkg, int argc, char **argv)
}
g_free (arg);
++i;
}
@ -756,7 +762,6 @@ parse_libs (Package *pkg, const char *str, const char *path)
exit (1);
}
_do_parse_libs(pkg, argc, argv);
g_free (trimmed);
@ -844,39 +849,30 @@ parse_cflags (Package *pkg, const char *str, const char *path)
i = 0;
while (i < argc)
{
char *arg = trim_string (argv[i]);
char *p;
char *start;
start = arg;
p = start;
char *tmp = trim_string (argv[i]);
char *arg = strdup_escape_shell(tmp);
char *p = arg;
g_free(tmp);
if (p[0] == '-' &&
p[1] == 'I')
{
char *libname;
p += 2;
while (*p && isspace ((guchar)*p))
++p;
start = p;
while (*p && !isspace ((guchar)*p))
++p;
libname = g_strndup (start, p - start);
pkg->I_cflags = g_slist_prepend (pkg->I_cflags,
g_strconcat ("-I", libname, NULL));
g_strconcat ("-I", p, NULL));
g_free (libname);
} else {
if (*arg != '\0')
pkg->other_cflags = g_slist_prepend (pkg->other_cflags,
g_strdup (arg));
if (strcmp("-idirafter", arg) == 0) {
char *n = trim_string(argv[++i]);
tmp = trim_string(argv[++i]);
char *n = strdup_escape_shell(tmp);
pkg->other_cflags = g_slist_prepend(pkg->other_cflags, n);
g_free(tmp);
}
}