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