msvc: handle quoting correctly for cmd.exe

feature/tap-sh
William Pitcock 2018-01-05 11:31:43 -06:00
parent 5d6c9ba98c
commit 7cce958d78
3 changed files with 46 additions and 43 deletions

View File

@ -19,17 +19,18 @@
#include <libpkgconf/libpkgconf.h> #include <libpkgconf/libpkgconf.h>
#include "renderer-msvc.h" #include "renderer-msvc.h"
static inline char * static inline bool
fragment_escape(const char *src) fragment_should_quote(const pkgconf_fragment_t *frag)
{ {
ssize_t outlen = strlen(src) + 10; const char *src;
char *out = calloc(outlen, 1);
char *dst = out;
while (*src) if (frag->data == NULL)
return false;
for (src = frag->data; *src; src++)
{ {
if (((*src < ' ') || if (((*src < ' ') ||
(*src > ' ' && *src < '$') || (*src >= (' ' + (frag->merged ? 1 : 0)) && *src < '$') ||
(*src > '$' && *src < '(') || (*src > '$' && *src < '(') ||
(*src > ')' && *src < '+') || (*src > ')' && *src < '+') ||
(*src > ':' && *src < '=') || (*src > ':' && *src < '=') ||
@ -37,34 +38,27 @@ fragment_escape(const char *src)
(*src > 'Z' && *src < '^') || (*src > 'Z' && *src < '^') ||
(*src == '`') || (*src == '`') ||
(*src > 'z' && *src < '~') || (*src > 'z' && *src < '~') ||
(*src > '~')) && *src != '\\') (*src > '~')))
*dst++ = '\\'; return true;
*dst++ = *src++;
if ((ptrdiff_t)(dst - out) + 2 > outlen)
{
outlen *= 2;
out = realloc(out, outlen);
}
} }
*dst = 0; return false;
return out;
} }
static inline size_t static inline size_t
fragment_len(const pkgconf_fragment_t *frag, bool escape) fragment_len(const pkgconf_fragment_t *frag)
{ {
size_t len = 1; size_t len = 1;
if (!escape) if (frag->type)
len += strlen(frag->data); len += 2;
else
if (frag->data != NULL)
{ {
char *tmp = fragment_escape(frag->data); len += strlen(frag->data);
len += strlen(tmp);
free(tmp); if (fragment_should_quote(frag))
len += 2;
} }
return len; return len;
@ -79,6 +73,8 @@ allowed_fragment(const pkgconf_fragment_t *frag)
static size_t static size_t
msvc_renderer_render_len(const pkgconf_list_t *list, bool escape) msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
{ {
(void) escape;
size_t out = 1; /* trailing nul */ size_t out = 1; /* trailing nul */
pkgconf_node_t *node; pkgconf_node_t *node;
@ -101,7 +97,7 @@ msvc_renderer_render_len(const pkgconf_list_t *list, bool escape)
break; break;
} }
out += fragment_len(frag, escape); out += fragment_len(frag);
} }
return out; return out;
@ -119,11 +115,12 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
{ {
const pkgconf_fragment_t *frag = node->data; const pkgconf_fragment_t *frag = node->data;
size_t buf_remaining = buflen - (bptr - buf); size_t buf_remaining = buflen - (bptr - buf);
size_t cnt;
if (!allowed_fragment(frag)) if (!allowed_fragment(frag))
continue; continue;
if (fragment_len(frag, escape) > buf_remaining) if (fragment_len(frag) > buf_remaining)
break; break;
if (frag->type == 'L') if (frag->type == 'L')
@ -133,21 +130,14 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
buf_remaining -= cnt; buf_remaining -= cnt;
} }
if (!escape) escape = fragment_should_quote(frag);
{
size_t cnt = pkgconf_strlcpy(bptr, frag->data, buf_remaining);
bptr += cnt;
buf_remaining -= cnt;
}
else
{
char *tmp = fragment_escape(frag->data);
size_t cnt = pkgconf_strlcpy(bptr, tmp, buf_remaining);
free(tmp);
bptr += cnt; if (escape)
buf_remaining -= cnt; *bptr++ = '"';
}
cnt = pkgconf_strlcpy(bptr, frag->data, buf_remaining);
bptr += cnt;
buf_remaining -= cnt;
if (frag->type == 'l') if (frag->type == 'l')
{ {
@ -156,6 +146,9 @@ msvc_renderer_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, b
buf_remaining -= cnt; buf_remaining -= cnt;
} }
if (escape)
*bptr++ = '"';
*bptr++ = ' '; *bptr++ = ' ';
} }

View File

@ -2,3 +2,4 @@ Name: fragment-escaping-1
Version: 0 Version: 0
Description: fragment escaping test Description: fragment escaping test
Cflags: "-IC:\\D E" Cflags: "-IC:\\D E"
Libs: "-LC:\\D E" -lE

View File

@ -27,7 +27,8 @@ tests_init \
fragment_quoting_2 \ fragment_quoting_2 \
fragment_quoting_3 \ fragment_quoting_3 \
fragment_quoting_5 \ fragment_quoting_5 \
fragment_quoting_7 fragment_quoting_7 \
msvc_fragment_quoting
comments_body() comments_body()
{ {
@ -248,3 +249,11 @@ fragment_quoting_7a_body()
set +x set +x
} }
msvc_fragment_quoting_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
atf_check \
-o inline:'/libpath:"C:\D E" E.lib \n' \
pkgconf --libs --msvc-syntax fragment-escaping-1
}