[geany/geany] 2f0c96: Improved blanks handling in Windows command lines
Dimitar Zhekov
git-noreply at xxxxx
Fri May 15 17:07:40 UTC 2015
Branch: refs/heads/master
Author: Dimitar Zhekov <dimitar.zhekov at gmail.com>
Committer: Dimitar Zhekov <dimitar.zhekov at gmail.com>
Date: Sat, 04 Apr 2015 16:46:45 UTC
Commit: 2f0c9686e23b96544fef66073f4ff1e772a0e921
https://github.com/geany/geany/commit/2f0c9686e23b96544fef66073f4ff1e772a0e921
Log Message:
-----------
Improved blanks handling in Windows command lines
The argument quoting must be permissive (g_ascii_isspace() doesn't
handle '\v'), the program name to arguments separator must be fixed
to restrictive, and the leading spaces are somewhere between.
Also fixed the test program to check for exactly 2 arguments.
Modified Paths:
--------------
src/spawn.c
Modified: src/spawn.c
24 lines changed, 16 insertions(+), 8 deletions(-)
===================================================================
@@ -49,6 +49,7 @@
#include "spawn.h"
#ifdef G_OS_WIN32
+# include <ctype.h> /* isspace() */
# include <fcntl.h> /* _O_RDONLY, _O_WRONLY */
# include <io.h> /* _open_osfhandle, _close */
# include <windows.h>
@@ -63,7 +64,6 @@
#endif
#ifdef G_OS_WIN32
-# define CL_BLANKS " \t" /* possible blank characters in a Windows command line */
/* Each 4KB under Windows seem to come in 2 portions, so 2K + 2K is more
balanced than 4095 + 1. May be different on the latest Windows/glib? */
# define DEFAULT_IO_LENGTH 2048
@@ -78,17 +78,19 @@
* Checks whether a command line is syntactically valid and extracts the program name from it.
*
* All OS:
- * - any leading spaces and tabs are ignored
- * - a command consisting solely of spaces and tabs is invalid
+ * - any leading spaces, tabs and new lines are skipped
+ * - an empty command is invalid
* Unix:
* - the standard shell quoting and escaping rules are used, see @c g_shell_parse_argv()
* - as a consequence, an unqouted # at the start of an argument comments to the end of line
* Windows:
+ * - leading carriage returns are skipped too
* - a quoted program name must be entirely inside the quotes. No "C:\Foo\Bar".pdf or
* "C:\Foo\Bar".bat, which would be executed by Windows as C:\Foo\Bar.exe
* - an unquoted program name may not contain spaces. Foo Bar Qux will not be considered
* "Foo Bar.exe" Qux or "Foo Bar Qux.exe", depending on what executables exist, as
* Windows normally does.
+ * - the program name must be separated from the arguments by at least one space or tab
* - the standard Windows quoting and escaping rules are used: double quote is escaped with
* backslash, and any literal backslashes before a double quote must be duplicated.
*
@@ -107,7 +109,7 @@ gchar *spawn_get_program_name(const gchar *command_line, GError **error)
g_return_val_if_fail(command_line != NULL, FALSE);
- while (*command_line && strchr(CL_BLANKS, *command_line))
+ while (*command_line && strchr(" \t\r\n", *command_line))
command_line++;
if (!*command_line)
@@ -118,6 +120,9 @@ gchar *spawn_get_program_name(const gchar *command_line, GError **error)
return FALSE;
}
+ /* To prevent Windows from doing something weird, we want to be 100% sure that the
+ character after the program name is a delimiter, so we allow space and tab only. */
+
if (*command_line == '"')
{
command_line++;
@@ -131,7 +136,7 @@ gchar *spawn_get_program_name(const gchar *command_line, GError **error)
return FALSE;
}
- if (!strchr(CL_BLANKS, s[1])) /* strchr() catches s[1] == '\0' */
+ if (!strchr(" \t", s[1])) /* strchr() catches s[1] == '\0' */
{
g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING,
_("A quoted Windows program name must be entirely inside the quotes"));
@@ -143,7 +148,7 @@ gchar *spawn_get_program_name(const gchar *command_line, GError **error)
const gchar *quote = strchr(command_line, '"');
/* strchr() catches *s == '\0', and the for body is empty */
- for (s = command_line; !strchr(CL_BLANKS, *s); s++);
+ for (s = command_line; !strchr(" \t", *s); s++);
if (quote && quote < s)
{
@@ -388,8 +393,11 @@ static void spawn_append_argument(GString *command, const char *text)
g_string_append_c(command, ' ');
for (s = text; *s; s++)
- if (*s == '"' || g_ascii_isspace(*s)) /* are all RTL-s standartized? */
+ {
+ /* g_ascii_isspace() fails for '\v', and locale spaces (if any) will do no harm */
+ if (*s == '"' || isspace(*s))
break;
+ }
if (*text && !*s)
g_string_append(command, text);
@@ -1153,7 +1161,7 @@ int main(int argc, char **argv)
{
char *test_type;
- if (argc < 2)
+ if (argc != 2)
{
fputs("usage: spawn <test-type>\n", stderr);
return 1;
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Commits
mailing list