mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	We now send argv to the server after parsing it in the client to get the
command, so the client should not modify it. Instead, take a copy. Fixes parsing command lists, reported by mcbride@.
This commit is contained in:
		
							
								
								
									
										20
									
								
								cmd-list.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								cmd-list.c
									
									
									
									
									
								
							@@ -29,7 +29,9 @@ cmd_list_parse(int argc, char **argv, char **cause)
 | 
				
			|||||||
	struct cmd	*cmd;
 | 
						struct cmd	*cmd;
 | 
				
			||||||
	int		 i, lastsplit;
 | 
						int		 i, lastsplit;
 | 
				
			||||||
	size_t		 arglen, new_argc;
 | 
						size_t		 arglen, new_argc;
 | 
				
			||||||
	char	       **new_argv;
 | 
						char	       **copy_argv, **new_argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						copy_argv = cmd_copy_argv(argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmdlist = xmalloc(sizeof *cmdlist);
 | 
						cmdlist = xmalloc(sizeof *cmdlist);
 | 
				
			||||||
	cmdlist->references = 1;
 | 
						cmdlist->references = 1;
 | 
				
			||||||
@@ -37,18 +39,18 @@ cmd_list_parse(int argc, char **argv, char **cause)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	lastsplit = 0;
 | 
						lastsplit = 0;
 | 
				
			||||||
	for (i = 0; i < argc; i++) {
 | 
						for (i = 0; i < argc; i++) {
 | 
				
			||||||
		arglen = strlen(argv[i]);
 | 
							arglen = strlen(copy_argv[i]);
 | 
				
			||||||
		if (arglen == 0 || argv[i][arglen - 1] != ';')
 | 
							if (arglen == 0 || copy_argv[i][arglen - 1] != ';')
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		argv[i][arglen - 1] = '\0';
 | 
							copy_argv[i][arglen - 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (arglen > 1 && argv[i][arglen - 2] == '\\') {
 | 
							if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') {
 | 
				
			||||||
			argv[i][arglen - 2] = ';';
 | 
								copy_argv[i][arglen - 2] = ';';
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		new_argc = i - lastsplit;
 | 
							new_argc = i - lastsplit;
 | 
				
			||||||
		new_argv = argv + lastsplit;
 | 
							new_argv = copy_argv + lastsplit;
 | 
				
			||||||
		if (arglen != 1)
 | 
							if (arglen != 1)
 | 
				
			||||||
			new_argc++;
 | 
								new_argc++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -61,16 +63,18 @@ cmd_list_parse(int argc, char **argv, char **cause)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (lastsplit != argc) {
 | 
						if (lastsplit != argc) {
 | 
				
			||||||
		cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
 | 
							cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit, cause);
 | 
				
			||||||
		if (cmd == NULL)
 | 
							if (cmd == NULL)
 | 
				
			||||||
			goto bad;
 | 
								goto bad;
 | 
				
			||||||
		TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
 | 
							TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_free_argv(argc, copy_argv);
 | 
				
			||||||
	return (cmdlist);
 | 
						return (cmdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bad:
 | 
					bad:
 | 
				
			||||||
	cmd_list_free(cmdlist);
 | 
						cmd_list_free(cmdlist);
 | 
				
			||||||
 | 
						cmd_free_argv(argc, copy_argv);
 | 
				
			||||||
	return (NULL);
 | 
						return (NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								cmd.c
									
									
									
									
									
								
							@@ -166,6 +166,22 @@ cmd_unpack_argv(char *buf, size_t len, int argc, char ***argv)
 | 
				
			|||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char **
 | 
				
			||||||
 | 
					cmd_copy_argv(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char	**new_argv;
 | 
				
			||||||
 | 
						int	  i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc == 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						new_argv = xcalloc(argc, sizeof *new_argv);
 | 
				
			||||||
 | 
						for (i = 0; i < argc; i++) {
 | 
				
			||||||
 | 
							if (argv[i] != NULL)
 | 
				
			||||||
 | 
								new_argv[i] = xstrdup(argv[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (new_argv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
cmd_free_argv(int argc, char **argv)
 | 
					cmd_free_argv(int argc, char **argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1464,6 +1464,7 @@ const char	*cmd_set_option_print(
 | 
				
			|||||||
/* cmd.c */
 | 
					/* cmd.c */
 | 
				
			||||||
int		 cmd_pack_argv(int, char **, char *, size_t);
 | 
					int		 cmd_pack_argv(int, char **, char *, size_t);
 | 
				
			||||||
int		 cmd_unpack_argv(char *, size_t, int, char ***);
 | 
					int		 cmd_unpack_argv(char *, size_t, int, char ***);
 | 
				
			||||||
 | 
					char	       **cmd_copy_argv(int, char **);
 | 
				
			||||||
void		 cmd_free_argv(int, char **);
 | 
					void		 cmd_free_argv(int, char **);
 | 
				
			||||||
struct cmd	*cmd_parse(int, char **, char **);
 | 
					struct cmd	*cmd_parse(int, char **, char **);
 | 
				
			||||||
int		 cmd_exec(struct cmd *, struct cmd_ctx *);
 | 
					int		 cmd_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user