{"thread":{"id":"1146","subject":"git-pull-script hates me","startedAt":"2005-07-06T20:31:39Z","lastAt":"2005-07-08T07:02:52Z","messageCount":10,"participants":["Greg KH","Linus Torvalds","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"5732","messageId":"20050706203139.GA19198@kroah.com","threadId":"1146","inReplyTo":null,"subject":"git-pull-script hates me","fromName":"Greg KH","fromEmail":"greg@kroah.com","sentAt":"2005-07-06T20:31:39Z","receivedAt":"2005-07-06T20:31:39Z","isPatch":false,"sender":{"key":"greg@kroah.com","avatar":"https://gravatar.com/avatar/5bb5aa0cc2e01c00ec899d11130c07796bc186e465bae57bc34873b13b72c7c8?d=mp&s=160"},"body":"I just updated to the latest git tree, and now get the following when I\ntry to pull from a ssh repo:\n\n $ git-pull-script gregkh@someserver.org:/public_html/udev.git/\n fatal: I don't like '@'. Sue me.\n\nSo I drop the @ and then get:\n $ git-pull-script someserver.org:/public_html/udev.git/\n fatal: I don't like '_'. Sue me.\n\nThis worked just fine before I updated git :(\n\nAny hints?  Or should I be using a different command to do pulls?\n\nthanks,\n\ngreg k-h\n"},{"id":"5733","messageId":"Pine.LNX.4.58.0507061335100.4159@g5.osdl.org","threadId":"1146","inReplyTo":"20050706203139.GA19198@kroah.com","subject":"Re: git-pull-script hates me","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-07-06T20:37:55Z","receivedAt":"2005-07-06T20:37:55Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 6 Jul 2005, Greg KH wrote:\n>\n> I just updated to the latest git tree, and now get the following when I\n> try to pull from a ssh repo:\n> \n>  $ git-pull-script gregkh@someserver.org:/public_html/udev.git/\n>  fatal: I don't like '@'. Sue me.\n> \n> So I drop the @ and then get:\n>  $ git-pull-script someserver.org:/public_html/udev.git/\n>  fatal: I don't like '_'. Sue me.\n\nHeh. It really is personal.\n\nThe new git-pack handling tries to avoid special characters, because it \npasses some things off to a shell (ie it opens up an ssh connection.\n\nBut yeah, it's being a bit too anal. Just look at connect.c: shell_safe(),\nand add both '_' and '@' to the safe list (and any other safe characters),\nand off you go.\n\nAnd if somebody wants to add code to do proper escaping of the non-safe \nones, we can do that too. I was just lazy and added the characters I ever \nuse ;)\n\n\t\tLinus\n"},{"id":"5737","messageId":"20050706204627.GA19481@kroah.com","threadId":"1146","inReplyTo":"Pine.LNX.4.58.0507061335100.4159@g5.osdl.org","subject":"Re: git-pull-script hates me","fromName":"Greg KH","fromEmail":"greg@kroah.com","sentAt":"2005-07-06T20:46:27Z","receivedAt":"2005-07-06T20:46:27Z","isPatch":false,"sender":{"key":"greg@kroah.com","avatar":"https://gravatar.com/avatar/5bb5aa0cc2e01c00ec899d11130c07796bc186e465bae57bc34873b13b72c7c8?d=mp&s=160"},"body":"On Wed, Jul 06, 2005 at 01:37:55PM -0700, Linus Torvalds wrote:\n> \n> \n> On Wed, 6 Jul 2005, Greg KH wrote:\n> >\n> > I just updated to the latest git tree, and now get the following when I\n> > try to pull from a ssh repo:\n> > \n> >  $ git-pull-script gregkh@someserver.org:/public_html/udev.git/\n> >  fatal: I don't like '@'. Sue me.\n> > \n> > So I drop the @ and then get:\n> >  $ git-pull-script someserver.org:/public_html/udev.git/\n> >  fatal: I don't like '_'. Sue me.\n> \n> Heh. It really is personal.\n> \n> The new git-pack handling tries to avoid special characters, because it \n> passes some things off to a shell (ie it opens up an ssh connection.\n> \n> But yeah, it's being a bit too anal. Just look at connect.c: shell_safe(),\n> and add both '_' and '@' to the safe list (and any other safe characters),\n> and off you go.\n\nOk, below is a patch for this.  It works, but then errors out with:\n\tbash: git-upload-pack: command not found\n\tfatal: unexpected EOF\n\nSo I'm guessing that I have to convince the server owner to update their\nversion of git too?\n\nthanks,\n\ngreg k-h\n\n--------------------\n\nSubject: allow _ and @ in addresses\n\nSigned-off-by: Greg Kroah-Hartman <gregkh@suse.de>\n\ndiff --git a/connect.c b/connect.c\n--- a/connect.c\n+++ b/connect.c\n@@ -57,6 +57,7 @@ static char *shell_safe(char *url)\n \t\t['A'...'Z'] = 1,\n \t\t['.'] = 1, ['/'] = 1,\n \t\t['-'] = 1, ['+'] = 1,\n+\t\t['@'] = 1, ['_'] = 1,\n \t\t[':'] = 1\n \t};\n \n"},{"id":"5734","messageId":"20050706205442.GA19653@kroah.com","threadId":"1146","inReplyTo":"20050706204627.GA19481@kroah.com","subject":"Re: git-pull-script hates me","fromName":"Greg KH","fromEmail":"greg@kroah.com","sentAt":"2005-07-06T20:54:42Z","receivedAt":"2005-07-06T20:54:42Z","isPatch":false,"sender":{"key":"greg@kroah.com","avatar":"https://gravatar.com/avatar/5bb5aa0cc2e01c00ec899d11130c07796bc186e465bae57bc34873b13b72c7c8?d=mp&s=160"},"body":"On Wed, Jul 06, 2005 at 01:46:27PM -0700, Greg KH wrote:\n> Ok, below is a patch for this.  It works, but then errors out with:\n> \tbash: git-upload-pack: command not found\n> \tfatal: unexpected EOF\n> \n> So I'm guessing that I have to convince the server owner to update their\n> version of git too?\n\nOk, so they did that, and the pull now works, sorry for the noise.\n\nthanks,\n\ngreg k-h\n"},{"id":"5735","messageId":"Pine.LNX.4.58.0507061357130.4675@g5.osdl.org","threadId":"1146","inReplyTo":"20050706204627.GA19481@kroah.com","subject":"Re: git-pull-script hates me","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-07-06T20:58:19Z","receivedAt":"2005-07-06T20:58:19Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 6 Jul 2005, Greg KH wrote:\n> \n> Ok, below is a patch for this.  It works, but then errors out with:\n> \tbash: git-upload-pack: command not found\n> \tfatal: unexpected EOF\n> \n> So I'm guessing that I have to convince the server owner to update their\n> version of git too?\n\nThe easiest way is to just build git on the other end yourself, and make\nsure you have\n\n\tPATH=~/bin:$PATH\n\nin your .bashrc. That way you're not at the mercy of the sysadmin on the \nother side.\n\n\t\tLinus\n"},{"id":"5739","messageId":"7v64vnwrwg.fsf@assigned-by-dhcp.cox.net","threadId":"1146","inReplyTo":"Pine.LNX.4.58.0507061335100.4159@g5.osdl.org","subject":"Re: git-pull-script hates me","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-06T21:23:11Z","receivedAt":"2005-07-06T21:23:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"LT\" == Linus Torvalds <torvalds@osdl.org> writes:\n\nLT> But yeah, it's being a bit too anal. Just look at connect.c: shell_safe(),\nLT> and add both '_' and '@' to the safe list (and any other safe characters),\nLT> and off you go.\n\nLT> And if somebody wants to add code to do proper escaping of the non-safe \nLT> ones, we can do that too. I was just lazy and added the characters I ever \nLT> use ;)\n\nAnybody who is interested in doing this can just move\nsq_expand() from diff.c to some public library and expose it in\ncache.h.\n\nI am not going to do it myself immediately so there is no worry\nto race against me ;-).\n"},{"id":"5738","messageId":"Pine.LNX.4.58.0507061434010.3847@g5.osdl.org","threadId":"1146","inReplyTo":"7v64vnwrwg.fsf@assigned-by-dhcp.cox.net","subject":"Re: git-pull-script hates me","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2005-07-06T21:36:44Z","receivedAt":"2005-07-06T21:36:44Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Wed, 6 Jul 2005, Junio C Hamano wrote:\n> \n> Anybody who is interested in doing this can just move\n> sq_expand() from diff.c to some public library and expose it in\n> cache.h.\n\nNo, that doesn't work at all.\n\n\"sq_expand()\" tries to protect things inside single quotes. That's a \ntotally different problem (and btw, it does so badly: it doesn't quote '\\' \nfor example).\n\nFor a shell command line, there are _tons_ of special characters that you\nmustn't pass through. Things like ';', '<', '>', '&' all have magic\nmeaning and are not valid in the destination name. Not to mention just\nsimple whitespace.\n\n\t\tLinus\n"},{"id":"5807","messageId":"7vd5ptdbwl.fsf_-_@assigned-by-dhcp.cox.net","threadId":"1146","inReplyTo":"7v64vnwrwg.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Make sq_expand() available as sq_quote().","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-08T06:55:54Z","receivedAt":"2005-07-08T06:55:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"A useful shell safety helper sq_expand() was hidden as a static\nfunction in diff.c.  Extract it out and make it available as\nsq_quote().\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n>>>>> \"JCH\" == Junio C Hamano <junkio@cox.net> writes:\n\nJCH> I am not going to do it myself immediately so there is no worry\nJCH> to race against me ;-).\n\nWell, I ended up doing it myself just as a diversion from\nthinking about pulls ;-).  As you said, one _must_ be very\ncareful when feeding a shell, but being careful does not\nnecessarily hard.\n\nThis is the first part; the next one will depend on it.\n\n Makefile |    3 +++\n diff.c   |   47 ++++++-----------------------------------------\n 2 files changed, 9 insertions(+), 41 deletions(-)\n\n0ab0d4c45dc7c531dd54f2d29a2199d4f4192018\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -65,6 +65,9 @@ LIB_H=cache.h object.h blob.h tree.h com\n LIB_H += strbuf.h\n LIB_OBJS += strbuf.o\n \n+LIB_H += quote.h\n+LIB_OBJS += quote.o \n+\n LIB_H += diff.h count-delta.h\n LIB_OBJS += diff.o diffcore-rename.o diffcore-pickaxe.o diffcore-pathspec.o \\\n \tcount-delta.o diffcore-break.o diffcore-order.o\ndiff --git a/diff.c b/diff.c\n--- a/diff.c\n+++ b/diff.c\n@@ -5,6 +5,7 @@\n #include <sys/wait.h>\n #include <signal.h>\n #include \"cache.h\"\n+#include \"quote.h\"\n #include \"diff.h\"\n #include \"diffcore.h\"\n \n@@ -40,42 +41,6 @@ static const char *external_diff(void)\n \treturn external_diff_cmd;\n }\n \n-/* Help to copy the thing properly quoted for the shell safety.\n- * any single quote is replaced with '\\'', and the caller is\n- * expected to enclose the result within a single quote pair.\n- *\n- * E.g.\n- *  original     sq_expand     result\n- *  name     ==> name      ==> 'name'\n- *  a b      ==> a b       ==> 'a b'\n- *  a'b      ==> a'\\''b    ==> 'a'\\''b'\n- */\n-static char *sq_expand(const char *src)\n-{\n-\tstatic char *buf = NULL;\n-\tint cnt, c;\n-\tconst char *cp;\n-\tchar *bp;\n-\n-\t/* count bytes needed to store the quoted string. */\n-\tfor (cnt = 1, cp = src; *cp; cnt++, cp++)\n-\t\tif (*cp == '\\'')\n-\t\t\tcnt += 3;\n-\n-\tbuf = xmalloc(cnt);\n-\tbp = buf;\n-\twhile ((c = *src++)) {\n-\t\tif (c != '\\'')\n-\t\t\t*bp++ = c;\n-\t\telse {\n-\t\t\tbp = strcpy(bp, \"'\\\\''\");\n-\t\t\tbp += 4;\n-\t\t}\n-\t}\n-\t*bp = 0;\n-\treturn buf;\n-}\n-\n static struct diff_tempfile {\n \tconst char *name; /* filename external diff should read from */\n \tchar hex[41];\n@@ -167,16 +132,16 @@ static void builtin_diff(const char *nam\n \t\t\t int complete_rewrite)\n {\n \tint i, next_at, cmd_size;\n-\tconst char *diff_cmd = \"diff -L'%s%s' -L'%s%s'\";\n-\tconst char *diff_arg  = \"'%s' '%s'||:\"; /* \"||:\" is to return 0 */\n+\tconst char *diff_cmd = \"diff -L%s%s -L%s%s\";\n+\tconst char *diff_arg  = \"%s %s||:\"; /* \"||:\" is to return 0 */\n \tconst char *input_name_sq[2];\n \tconst char *path0[2];\n \tconst char *path1[2];\n \tconst char *name_sq[2];\n \tchar *cmd;\n \n-\tname_sq[0] = sq_expand(name_a);\n-\tname_sq[1] = sq_expand(name_b);\n+\tname_sq[0] = sq_quote(name_a);\n+\tname_sq[1] = sq_quote(name_b);\n \n \t/* diff_cmd and diff_arg have 6 %s in total which makes\n \t * the sum of these strings 12 bytes larger than required.\n@@ -186,7 +151,7 @@ static void builtin_diff(const char *nam\n \tcmd_size = (strlen(diff_cmd) + strlen(diff_opts) +\n \t\t\tstrlen(diff_arg) - 9);\n \tfor (i = 0; i < 2; i++) {\n-\t\tinput_name_sq[i] = sq_expand(temp[i].name);\n+\t\tinput_name_sq[i] = sq_quote(temp[i].name);\n \t\tif (!strcmp(temp[i].name, \"/dev/null\")) {\n \t\t\tpath0[i] = \"/dev/null\";\n \t\t\tpath1[i] = \"\";\n"},{"id":"5808","messageId":"7v3bqpdbs7.fsf@assigned-by-dhcp.cox.net","threadId":"1146","inReplyTo":"7v64vnwrwg.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Make sq_expand() available as sq_quote().","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-08T06:58:32Z","receivedAt":"2005-07-08T06:58:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"A useful shell safety helper sq_expand() was hidden as a static\nfunction in diff.c.  Extract it out and make it available as\nsq_quote().\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n>>>>> \"JCH\" == Junio C Hamano <junkio@cox.net> writes:\n\nJCH> I am not going to do it myself immediately so there is no worry\nJCH> to race against me ;-).\n\nWell, I ended up doing it myself just as a diversion from\nthinking about pulls ;-).  As you said, one _must_ be very\ncareful when feeding a shell, but being careful does not\nnecessarily hard.\n\nThis is the first part; the next one will depend on it.\n\n Makefile |    3 +++\n diff.c   |   47 ++++++-----------------------------------------\n quote.c  |   41 +++++++++++++++++++++++++++++++++++++++++\n quote.h  |   26 ++++++++++++++++++++++++++\n 4 files changed, 76 insertions(+), 41 deletions(-)\n create mode 100644 quote.c\n create mode 100644 quote.h\n\n500d2196566027419b1b8effc28f78eb9a60f086\ndiff --git a/Makefile b/Makefile\n--- a/Makefile\n+++ b/Makefile\n@@ -65,6 +65,9 @@ LIB_H=cache.h object.h blob.h tree.h com\n LIB_H += strbuf.h\n LIB_OBJS += strbuf.o\n \n+LIB_H += quote.h\n+LIB_OBJS += quote.o \n+\n LIB_H += diff.h count-delta.h\n LIB_OBJS += diff.o diffcore-rename.o diffcore-pickaxe.o diffcore-pathspec.o \\\n \tcount-delta.o diffcore-break.o diffcore-order.o\ndiff --git a/diff.c b/diff.c\n--- a/diff.c\n+++ b/diff.c\n@@ -5,6 +5,7 @@\n #include <sys/wait.h>\n #include <signal.h>\n #include \"cache.h\"\n+#include \"quote.h\"\n #include \"diff.h\"\n #include \"diffcore.h\"\n \n@@ -40,42 +41,6 @@ static const char *external_diff(void)\n \treturn external_diff_cmd;\n }\n \n-/* Help to copy the thing properly quoted for the shell safety.\n- * any single quote is replaced with '\\'', and the caller is\n- * expected to enclose the result within a single quote pair.\n- *\n- * E.g.\n- *  original     sq_expand     result\n- *  name     ==> name      ==> 'name'\n- *  a b      ==> a b       ==> 'a b'\n- *  a'b      ==> a'\\''b    ==> 'a'\\''b'\n- */\n-static char *sq_expand(const char *src)\n-{\n-\tstatic char *buf = NULL;\n-\tint cnt, c;\n-\tconst char *cp;\n-\tchar *bp;\n-\n-\t/* count bytes needed to store the quoted string. */\n-\tfor (cnt = 1, cp = src; *cp; cnt++, cp++)\n-\t\tif (*cp == '\\'')\n-\t\t\tcnt += 3;\n-\n-\tbuf = xmalloc(cnt);\n-\tbp = buf;\n-\twhile ((c = *src++)) {\n-\t\tif (c != '\\'')\n-\t\t\t*bp++ = c;\n-\t\telse {\n-\t\t\tbp = strcpy(bp, \"'\\\\''\");\n-\t\t\tbp += 4;\n-\t\t}\n-\t}\n-\t*bp = 0;\n-\treturn buf;\n-}\n-\n static struct diff_tempfile {\n \tconst char *name; /* filename external diff should read from */\n \tchar hex[41];\n@@ -167,16 +132,16 @@ static void builtin_diff(const char *nam\n \t\t\t int complete_rewrite)\n {\n \tint i, next_at, cmd_size;\n-\tconst char *diff_cmd = \"diff -L'%s%s' -L'%s%s'\";\n-\tconst char *diff_arg  = \"'%s' '%s'||:\"; /* \"||:\" is to return 0 */\n+\tconst char *diff_cmd = \"diff -L%s%s -L%s%s\";\n+\tconst char *diff_arg  = \"%s %s||:\"; /* \"||:\" is to return 0 */\n \tconst char *input_name_sq[2];\n \tconst char *path0[2];\n \tconst char *path1[2];\n \tconst char *name_sq[2];\n \tchar *cmd;\n \n-\tname_sq[0] = sq_expand(name_a);\n-\tname_sq[1] = sq_expand(name_b);\n+\tname_sq[0] = sq_quote(name_a);\n+\tname_sq[1] = sq_quote(name_b);\n \n \t/* diff_cmd and diff_arg have 6 %s in total which makes\n \t * the sum of these strings 12 bytes larger than required.\n@@ -186,7 +151,7 @@ static void builtin_diff(const char *nam\n \tcmd_size = (strlen(diff_cmd) + strlen(diff_opts) +\n \t\t\tstrlen(diff_arg) - 9);\n \tfor (i = 0; i < 2; i++) {\n-\t\tinput_name_sq[i] = sq_expand(temp[i].name);\n+\t\tinput_name_sq[i] = sq_quote(temp[i].name);\n \t\tif (!strcmp(temp[i].name, \"/dev/null\")) {\n \t\t\tpath0[i] = \"/dev/null\";\n \t\t\tpath1[i] = \"\";\ndiff --git a/quote.c b/quote.c\nnew file mode 100644\n--- /dev/null\n+++ b/quote.c\n@@ -0,0 +1,41 @@\n+#include \"cache.h\"\n+#include \"quote.h\"\n+\n+/* Help to copy the thing properly quoted for the shell safety.\n+ * any single quote is replaced with '\\'', and the caller is\n+ * expected to enclose the result within a single quote pair.\n+ *\n+ * E.g.\n+ *  original     sq_quote     result\n+ *  name     ==> name      ==> 'name'\n+ *  a b      ==> a b       ==> 'a b'\n+ *  a'b      ==> a'\\''b    ==> 'a'\\''b'\n+ */\n+char *sq_quote(const char *src)\n+{\n+\tstatic char *buf = NULL;\n+\tint cnt, c;\n+\tconst char *cp;\n+\tchar *bp;\n+\n+\t/* count bytes needed to store the quoted string. */\n+\tfor (cnt = 3, cp = src; *cp; cnt++, cp++)\n+\t\tif (*cp == '\\'')\n+\t\t\tcnt += 3;\n+\n+\tbuf = xmalloc(cnt);\n+\tbp = buf;\n+\t*bp++ = '\\'';\n+\twhile ((c = *src++)) {\n+\t\tif (c != '\\'')\n+\t\t\t*bp++ = c;\n+\t\telse {\n+\t\t\tbp = strcpy(bp, \"'\\\\''\");\n+\t\t\tbp += 4;\n+\t\t}\n+\t}\n+\t*bp++ = '\\'';\n+\t*bp = 0;\n+\treturn buf;\n+}\n+\ndiff --git a/quote.h b/quote.h\nnew file mode 100644\n--- /dev/null\n+++ b/quote.h\n@@ -0,0 +1,26 @@\n+#ifndef QUOTE_H\n+#define QUOTE_H\n+\n+\n+/* Help to copy the thing properly quoted for the shell safety.\n+ * any single quote is replaced with '\\'', and the whole thing\n+ * is enclosed in a single quote pair.\n+ *\n+ * For example, if you are passing the result to system() as an\n+ * argument:\n+ *\n+ * sprintf(cmd, \"foobar %s %s\", sq_quote(arg0), sq_quote(arg1))\n+ *\n+ * would be appropriate.  If the system() is going to call ssh to\n+ * run the command on the other side:\n+ *\n+ * sprintf(cmd, \"git-diff-tree %s %s\", sq_quote(arg0), sq_quote(arg1));\n+ * sprintf(rcmd, \"ssh %s %s\", sq_quote(host), sq_quote(cmd));\n+ *\n+ * Note that the above examples leak memory!  Remember to free result from\n+ * sq_quote() in a real application.\n+ */\n+\n+char *sq_quote(const char *src);\n+\n+#endif\n"},{"id":"5809","messageId":"7vslypbx0j.fsf_-_@assigned-by-dhcp.cox.net","threadId":"1146","inReplyTo":"7v3bqpdbs7.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Use sq_quote() to properly quote the parameter to call shell.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-08T07:02:52Z","receivedAt":"2005-07-08T07:02:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This tries to be more lenient to the users and stricter to the\nattackers by quoting the input properly for shell safety,\ninstead of forbidding certain characters from the input.\n\nThings to note:\n\n - We do not quote \"prog\" parameter (which comes from --exec).\n   The user should know what he is doing.  --exec='echo foo'\n   will supply the first two parameters to the resulting\n   command, while --exec=\"'echo foo'\" will give the first\n   parameter, a single string with a space inside.\n\n - We do not care too much about leaking the sq_quote() output\n   just before running exec().\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\nThis depends on the previous [PATCH] Make sq_expand() available as sq_quote().\nPlease discard the one I sent by mistake that lacks additions of\nquote.[ch] files.\n\nTo verify the stuff is quoted properly, I used the following\ncommand invocations.  They show that the metacharacters are\npassed unmolested by the intervening shell and ssh commands:\n\n    $ git-send-pack --exec=/bin/echo '0011 abc;d\\ef g<h'\n    fatal: protocol error: expected sha/ref, got ' abc;d\\ef g<h'\n    $ git-send-pack --exec=/bin/echo localhost:'0011 abc;d\\ef g<h'\n    fatal: protocol error: expected sha/ref, got ' abc;d\\ef g<h'\n    $ git-fetch-pack '0011 abc;d\\ef g<h' a\n    fatal: git-upload-pack unable to chdir to 0011 abc;d\\ef g<h\n    fatal: unexpected EOF\n    $ git-fetch-pack localhost:'0011 abc;d\\ef g<h' a\n    fatal: git-upload-pack unable to chdir to 0011 abc;d\\ef g<h\n    fatal: unexpected EOF\n\nAlso by storing the following executable script in\n/var/tmp/j0.sh and using git-send-pack --exec=/var/tmp/j0.sh\nwith the same parameters:\n\n    #!/bin/sh\n    o=/var/tmp/j0.out \n    echo $$ >>$o\n\n    i=0\n    echo \"0: [$0]\" >>$o\n    for x\n    do\n\ti=$(expr $i + 1)\n\techo \"$i: [$x]\" >>$o\n    done\n\nit can be verified that the funny string is indeed passed as a\nsingle parameter to it.\n\n connect.c |   33 +++------------------------------\n 1 files changed, 3 insertions(+), 30 deletions(-)\n\ne6e65f02919048f37467a9aca55ed19892dd2a7e\ndiff --git a/connect.c b/connect.c\n--- a/connect.c\n+++ b/connect.c\n@@ -1,5 +1,6 @@\n #include \"cache.h\"\n #include \"pkt-line.h\"\n+#include \"quote.h\"\n #include <sys/wait.h>\n \n int get_ack(int fd, unsigned char *result_sha1)\n@@ -42,34 +43,6 @@ int path_match(const char *path, int nr,\n }\n \n /*\n- * First, make it shell-safe.  We do this by just disallowing any\n- * special characters. Somebody who cares can do escaping and let\n- * through the rest. But since we're doing to feed this to ssh as\n- * a command line, we're going to be pretty damn anal for now.\n- */\n-static char *shell_safe(char *url)\n-{\n-\tchar *n = url;\n-\tunsigned char c;\n-\tstatic const char flags[256] = {\n-\t\t['0'...'9'] = 1,\n-\t\t['a'...'z'] = 1,\n-\t\t['A'...'Z'] = 1,\n-\t\t['.'] = 1, ['/'] = 1,\n-\t\t['-'] = 1, ['+'] = 1,\n-\t\t[':'] = 1, ['_'] = 1,\n-\t\t['@'] = 1, [','] = 1,\n-\t\t['~'] = 1, ['^'] = 1,\n-\t};\n-\n-\twhile ((c = *n++) != 0) {\n-\t\tif (flags[c] != 1)\n-\t\t\tdie(\"I don't like '%c'. Sue me.\", c);\n-\t}\n-\treturn url;\n-}\n-\n-/*\n  * Yeah, yeah, fixme. Need to pass in the heads etc.\n  */\n int git_connect(int fd[2], char *url, const char *prog)\n@@ -80,7 +53,6 @@ int git_connect(int fd[2], char *url, co\n \tint pipefd[2][2];\n \tpid_t pid;\n \n-\turl = shell_safe(url);\n \thost = NULL;\n \tpath = url;\n \tcolon = strchr(url, ':');\n@@ -89,11 +61,12 @@ int git_connect(int fd[2], char *url, co\n \t\thost = url;\n \t\tpath = colon+1;\n \t}\n-\tsnprintf(command, sizeof(command), \"%s %s\", prog, path);\n \tif (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)\n \t\tdie(\"unable to create pipe pair for communication\");\n \tpid = fork();\n \tif (!pid) {\n+\t\tsnprintf(command, sizeof(command), \"%s %s\", prog,\n+\t\t\t sq_quote(path));\n \t\tdup2(pipefd[1][0], 0);\n \t\tdup2(pipefd[0][1], 1);\n \t\tclose(pipefd[0][0]);\n"}]}