Better string escaping, but it's still not good enough to support paths
with spaces.
This commit is contained in:
		
							parent
							
								
									3e394b95e4
								
							
						
					
					
						commit
						6a3c94a9d0
					
				
					 1 changed files with 57 additions and 12 deletions
				
			
		| 
						 | 
					@ -2,34 +2,79 @@
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include "system.h"
 | 
					#include "system.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined WIN32
 | 
				
			||||||
 | 
						#define ESCAPECHAR '^'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static int needs_escaping(char c)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							switch (c)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								case ' ':
 | 
				
			||||||
 | 
								case '"':
 | 
				
			||||||
 | 
								case '\'':
 | 
				
			||||||
 | 
								case '(':
 | 
				
			||||||
 | 
								case ')':
 | 
				
			||||||
 | 
								case '^':
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						#define ESCAPECHAR '\\'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static int needs_escaping(char c)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							switch (c)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								case ' ':
 | 
				
			||||||
 | 
								case '"':
 | 
				
			||||||
 | 
								case '\'':
 | 
				
			||||||
 | 
								case '\\':
 | 
				
			||||||
 | 
								case '(':
 | 
				
			||||||
 | 
								case ')':
 | 
				
			||||||
 | 
									return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char* append_escaped(char* buffer, const char* word)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (;;)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char c = *word++;
 | 
				
			||||||
 | 
							if (!c)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (needs_escaping(c))
 | 
				
			||||||
 | 
								*buffer++ = ESCAPECHAR;
 | 
				
			||||||
 | 
							*buffer++ = c;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return buffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int sys_system(const char* prog, const char* const* arglist)
 | 
					int sys_system(const char* prog, const char* const* arglist)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* Calculate the maximum length of the command line. */
 | 
						/* Calculate the maximum length of the command line. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int len = strlen(prog);
 | 
						int len = strlen(prog) * 2 + 1;
 | 
				
			||||||
	for (const char* const* arg = arglist+1; *arg; arg++)
 | 
						for (const char* const* arg = arglist+1; *arg; arg++)
 | 
				
			||||||
		len += strlen(*arg) * 2 + 1;
 | 
							len += strlen(*arg) * 2 + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Now actually build the command line. */
 | 
						/* Now actually build the command line. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char* cmdline = malloc(len + 1);
 | 
						char* cmdline = malloc(len + 1);
 | 
				
			||||||
	strcpy(cmdline, prog);
 | 
						char* p = append_escaped(cmdline, prog);
 | 
				
			||||||
	char* p = cmdline + strlen(prog);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (const char* const* arg = arglist+1; *arg; arg++)
 | 
						for (const char* const* arg = arglist+1; *arg; arg++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const char* word = *arg;
 | 
							const char* word = *arg;
 | 
				
			||||||
		*p++ = ' ';
 | 
							*p++ = ' ';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (;;)
 | 
							p = append_escaped(p, word);
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			char c = *word++;
 | 
					 | 
				
			||||||
			if (!c)
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			if ((c == ' ') || (c == '\"') || (c == '\''))
 | 
					 | 
				
			||||||
				*p++ = '\\';
 | 
					 | 
				
			||||||
			*p++ = c;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	*p = 0;
 | 
						*p = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue