forked from pool/ctags
210 lines
6.1 KiB
Diff
210 lines
6.1 KiB
Diff
|
Based on
|
||
|
From e00c55d7a0204dc1d0ae316141323959e1e16162 Mon Sep 17 00:00:00 2001
|
||
|
From: Masatake YAMATO <yamato@redhat.com>
|
||
|
Date: Mon, 24 Oct 2016 23:52:23 +0900
|
||
|
Subject: [PATCH] main: quote output file name before passing it to system(3)
|
||
|
function
|
||
|
|
||
|
Following command line doesn't work:
|
||
|
|
||
|
$ ctags -o 'a b' ...
|
||
|
|
||
|
because a shell lauched from system(3) deals a whitespace between 'a'
|
||
|
and 'b' as a separator. The output file name is passed to system(3)
|
||
|
to run external sort command.
|
||
|
|
||
|
This commit adds code to put double and single quoets around the output
|
||
|
file name before passing it to system(3).
|
||
|
|
||
|
The issue is reported by Lorenz Hipp <lhipp@idealbonn.de> in a private mail.
|
||
|
|
||
|
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
|
||
|
---
|
||
|
Tmain/abnormal-output-file-names.d/input.c | 1 +
|
||
|
Tmain/abnormal-output-file-names.d/run.sh | 39 ++++++++++
|
||
|
.../stderr-expected.txt | 0
|
||
|
.../stdout-expected.txt | 8 +++
|
||
|
main/sort.c | 72 ++++++++++++++-----
|
||
|
5 files changed, 102 insertions(+), 18 deletions(-)
|
||
|
create mode 100644 Tmain/abnormal-output-file-names.d/input.c
|
||
|
create mode 100644 Tmain/abnormal-output-file-names.d/run.sh
|
||
|
create mode 100644 Tmain/abnormal-output-file-names.d/stderr-expected.txt
|
||
|
create mode 100644 Tmain/abnormal-output-file-names.d/stdout-expected.txt
|
||
|
|
||
|
Index: ctags-5.8/Tmain/abnormal-output-file-names.d/input.c
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ctags-5.8/Tmain/abnormal-output-file-names.d/input.c
|
||
|
@@ -0,0 +1 @@
|
||
|
+int x;
|
||
|
Index: ctags-5.8/Tmain/abnormal-output-file-names.d/run.sh
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ctags-5.8/Tmain/abnormal-output-file-names.d/run.sh
|
||
|
@@ -0,0 +1,39 @@
|
||
|
+# Copyright: 2016 Masatake YAMATO
|
||
|
+# License: GPL-2
|
||
|
+
|
||
|
+CTAGS=$1
|
||
|
+
|
||
|
+rm -f ./"'"
|
||
|
+rm -f ./'"'
|
||
|
+rm -f ./'$(ls)'
|
||
|
+rm -f ./'a b'
|
||
|
+
|
||
|
+${CTAGS} --options=NONE -o ./"'" --extra=-pF input.c
|
||
|
+${CTAGS} --options=NONE -o ./'"' --extra=-pF input.c
|
||
|
+${CTAGS} --options=NONE -o ./'$(ls)' --extra=-pF input.c
|
||
|
+${CTAGS} --options=NONE -o ./'a b' --extra=-pF input.c
|
||
|
+
|
||
|
+echo '#' SINGLE QUOTE
|
||
|
+if [ -e "'" ]; then
|
||
|
+ cat "'"
|
||
|
+fi
|
||
|
+
|
||
|
+echo '#' DOUBLE QUOTES
|
||
|
+if [ -e '"' ]; then
|
||
|
+ cat '"'
|
||
|
+fi
|
||
|
+
|
||
|
+echo '#' PROCESS SUBSTITUTION
|
||
|
+if [ -e '$(ls)' ]; then
|
||
|
+ cat '$(ls)'
|
||
|
+fi
|
||
|
+
|
||
|
+echo '#' SPACE
|
||
|
+if [ -e 'a b' ]; then
|
||
|
+ cat 'a b'
|
||
|
+fi
|
||
|
+
|
||
|
+rm -f ./"'"
|
||
|
+rm -f ./'"'
|
||
|
+rm -f ./'$(ls)'
|
||
|
+rm -f ./'a b'
|
||
|
Index: ctags-5.8/Tmain/abnormal-output-file-names.d/stdout-expected.txt
|
||
|
===================================================================
|
||
|
--- /dev/null
|
||
|
+++ ctags-5.8/Tmain/abnormal-output-file-names.d/stdout-expected.txt
|
||
|
@@ -0,0 +1,8 @@
|
||
|
+# SINGLE QUOTE
|
||
|
+x input.c /^int x;$/;" v typeref:typename:int
|
||
|
+# DOUBLE QUOTES
|
||
|
+x input.c /^int x;$/;" v typeref:typename:int
|
||
|
+# PROCESS SUBSTITUTION
|
||
|
+x input.c /^int x;$/;" v typeref:typename:int
|
||
|
+# SPACE
|
||
|
+x input.c /^int x;$/;" v typeref:typename:int
|
||
|
Index: ctags-5.8/sort.c
|
||
|
===================================================================
|
||
|
--- ctags-5.8.orig/sort.c
|
||
|
+++ ctags-5.8/sort.c
|
||
|
@@ -19,6 +19,7 @@
|
||
|
#endif
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
+#include <unistd.h>
|
||
|
|
||
|
#include "debug.h"
|
||
|
#include "entry.h"
|
||
|
@@ -53,41 +54,83 @@ extern void catFile (const char *const n
|
||
|
# define PE_CONST const
|
||
|
#endif
|
||
|
|
||
|
+/*
|
||
|
+ Output file name should not be evaluated in system(3) function.
|
||
|
+ The name must be used as is. Quotations are required to block the
|
||
|
+ evaluation.
|
||
|
+
|
||
|
+ Normal single-quotes are used to quote a cstring:
|
||
|
+ a => 'a'
|
||
|
+ " => '"'
|
||
|
+
|
||
|
+ If a single-quote is included in the cstring, use double quotes for quoting it.
|
||
|
+ ' => ''"'"''
|
||
|
+*/
|
||
|
+static void appendCstringWithQuotes (vString *dest, const char* cstr)
|
||
|
+{
|
||
|
+ const char* o;
|
||
|
+
|
||
|
+ vStringPut (dest, '\'');
|
||
|
+ for (o = cstr; *o; o++)
|
||
|
+ {
|
||
|
+ if (*o == '\'')
|
||
|
+ vStringCatS (dest, "'\"'\"'");
|
||
|
+ else
|
||
|
+ vStringPut (dest, *o);
|
||
|
+ }
|
||
|
+ vStringPut (dest, '\'');
|
||
|
+}
|
||
|
+
|
||
|
extern void externalSortTags (const boolean toStdout)
|
||
|
{
|
||
|
- const char *const sortNormalCommand = "sort -u -o";
|
||
|
- const char *const sortFoldedCommand = "sort -u -f -o";
|
||
|
+ const char *const sortNormalCommand = "/usr/bin/sort -u";
|
||
|
+ const char *const sortFoldedCommand = "/usr/bin/sort -u -f";
|
||
|
const char *sortCommand =
|
||
|
Option.sorted == SO_FOLDSORTED ? sortFoldedCommand : sortNormalCommand;
|
||
|
+# ifndef HAVE_SETENV
|
||
|
PE_CONST char *const sortOrder1 = "LC_COLLATE=C";
|
||
|
PE_CONST char *const sortOrder2 = "LC_ALL=C";
|
||
|
- const size_t length = 4 + strlen (sortOrder1) + strlen (sortOrder2) +
|
||
|
- strlen (sortCommand) + (2 * strlen (tagFileName ()));
|
||
|
- char *const cmd = (char *) malloc (length + 1);
|
||
|
+# endif
|
||
|
+ vString *cmd = vStringNew ();
|
||
|
int ret = -1;
|
||
|
|
||
|
if (cmd != NULL)
|
||
|
{
|
||
|
/* Ensure ASCII value sort order.
|
||
|
*/
|
||
|
-#ifdef HAVE_SETENV
|
||
|
+#if defined(HAVE_SETENV) || defined(HAVE_PUTENV)
|
||
|
+# if HAVE_SETENV
|
||
|
setenv ("LC_COLLATE", "C", 1);
|
||
|
setenv ("LC_ALL", "C", 1);
|
||
|
- sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), tagFileName ());
|
||
|
-#else
|
||
|
-# ifdef HAVE_PUTENV
|
||
|
+# else
|
||
|
putenv (sortOrder1);
|
||
|
putenv (sortOrder2);
|
||
|
- sprintf (cmd, "%s %s %s", sortCommand, tagFileName (), tagFileName ());
|
||
|
-# else
|
||
|
- sprintf (cmd, "%s %s %s %s %s", sortOrder1, sortOrder2, sortCommand,
|
||
|
- tagFileName (), tagFileName ());
|
||
|
# endif
|
||
|
+ vStringCatS (cmd, sortCommand);
|
||
|
+// if (! toStdout)
|
||
|
+ {
|
||
|
+ vStringCatS (cmd, " -o ");
|
||
|
+ appendCstringWithQuotes (cmd, tagFileName ());
|
||
|
+ vStringPut (cmd, ' ');
|
||
|
+ appendCstringWithQuotes (cmd, tagFileName ());
|
||
|
+ }
|
||
|
+#else
|
||
|
+ vStringCatS (cmd, sortOrder1);
|
||
|
+ vStringPut (cmd, ' ');
|
||
|
+ vStringCatS (cmd, sortOrder2);
|
||
|
+ vStringPut (cmd, ' ');
|
||
|
+ vStringCatS (cmd, sortCommand);
|
||
|
+// if (! toStdout)
|
||
|
+ {
|
||
|
+ vStringCats (cmd, " -o ");
|
||
|
+ appendCstringWithQuotes (cmd, tagFileName ());
|
||
|
+ vStringPut (cmd, ' ');
|
||
|
+ appendCstringWithQuotes (cmd, tagFileName ());
|
||
|
+ }
|
||
|
#endif
|
||
|
- verbose ("system (\"%s\")\n", cmd);
|
||
|
- ret = system (cmd);
|
||
|
- free (cmd);
|
||
|
-
|
||
|
+ verbose ("system (\"%s\")\n", vStringValue(cmd));
|
||
|
+ ret = system (vStringValue(cmd));
|
||
|
+ vStringDelete (cmd);
|
||
|
}
|
||
|
if (ret != 0)
|
||
|
error (FATAL | PERROR, "cannot sort tag file");
|