mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Give each paste buffer a size member instead of requiring them to be
zero-terminated.
This commit is contained in:
		| @@ -16,7 +16,10 @@ | ||||
|  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "tmux.h" | ||||
|  | ||||
| @@ -122,34 +125,38 @@ cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| { | ||||
| 	struct cmd_copy_buffer_data	*data = self->data; | ||||
| 	struct paste_buffer		*pb; | ||||
| 	struct paste_stack		*dst_ps, *src_ps; | ||||
| 	u_char				*pdata; | ||||
| 	struct session			*dst_session, *src_session; | ||||
| 	u_int				 limit; | ||||
|  | ||||
| 	if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL || | ||||
| 	    (src_session = cmd_find_session(ctx, data->src_session)) == NULL) | ||||
| 	    	return (-1); | ||||
| 	dst_ps = &dst_session->buffers; | ||||
| 	src_ps = &src_session->buffers; | ||||
|  | ||||
| 	if (data->src_idx == -1) { | ||||
| 		if ((pb = paste_get_top(&src_session->buffers)) == NULL) { | ||||
| 		if ((pb = paste_get_top(src_ps)) == NULL) { | ||||
| 			ctx->error(ctx, "no buffers"); | ||||
| 			return (-1); | ||||
| 		} | ||||
| 	} else { | ||||
| 		if ((pb = paste_get_index(&src_session->buffers, | ||||
| 		    data->src_idx)) == NULL) { | ||||
| 		if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) { | ||||
| 		    	ctx->error(ctx, "no buffer %d", data->src_idx); | ||||
| 		    	return (-1); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	limit = options_get_number(&dst_session->options, "buffer-limit"); | ||||
| 	if (data->dst_idx == -1) { | ||||
| 		paste_add(&dst_session->buffers, xstrdup(pb->data), limit); | ||||
| 		return (0); | ||||
| 	} | ||||
| 	if (paste_replace(&dst_session->buffers, data->dst_idx, | ||||
| 	    xstrdup(pb->data)) != 0) { | ||||
|  | ||||
| 	pdata = xmalloc(pb->size); | ||||
| 	memcpy(pdata, pb->data, pb->size); | ||||
|  | ||||
| 	if (data->dst_idx == -1) | ||||
| 		paste_add(dst_ps, pdata, pb->size, limit); | ||||
| 	else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) { | ||||
| 		ctx->error(ctx, "no buffer %d", data->dst_idx); | ||||
| 		xfree(pdata); | ||||
| 		return (-1); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -55,7 +55,7 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
|  | ||||
| 	idx = 0; | ||||
| 	while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) { | ||||
| 		size = strlen(pb->data); | ||||
| 		size = pb->size; | ||||
|  | ||||
| 		/* Translate the first 50 characters. */ | ||||
| 		len = size; | ||||
|   | ||||
| @@ -48,15 +48,15 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| { | ||||
| 	struct cmd_buffer_data	*data = self->data; | ||||
| 	struct session		*s; | ||||
| 	struct stat		statbuf; | ||||
| 	struct stat		 sb; | ||||
| 	FILE			*f; | ||||
| 	char			*buf; | ||||
| 	u_char		      	*buf; | ||||
| 	u_int			 limit; | ||||
|  | ||||
| 	if ((s = cmd_find_session(ctx, data->target)) == NULL) | ||||
| 		return (-1); | ||||
|  | ||||
| 	if (stat(data->arg, &statbuf) < 0) { | ||||
| 	if (stat(data->arg, &sb) < 0) { | ||||
| 		ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); | ||||
| 		return (-1); | ||||
| 	} | ||||
| @@ -70,28 +70,27 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| 	 * We don't want to die due to memory exhaustion, hence xmalloc can't | ||||
| 	 * be used here. | ||||
| 	 */ | ||||
| 	if ((buf = malloc(statbuf.st_size + 1)) == NULL) { | ||||
| 	if ((buf = malloc(sb.st_size + 1)) == NULL) { | ||||
| 		ctx->error(ctx, "malloc error: %s", strerror(errno)); | ||||
| 		fclose(f); | ||||
| 		return (-1); | ||||
| 	} | ||||
|  | ||||
| 	if (fread(buf, 1, statbuf.st_size, f) != (size_t) statbuf.st_size) { | ||||
| 	if (fread(buf, 1, sb.st_size, f) != (size_t) sb.st_size) { | ||||
| 		ctx->error(ctx, "%s: fread error", data->arg); | ||||
| 		xfree(buf); | ||||
| 		fclose(f); | ||||
| 		return (-1); | ||||
| 	} | ||||
|  | ||||
| 	buf[statbuf.st_size] = '\0'; | ||||
| 	fclose(f); | ||||
|  | ||||
| 	limit = options_get_number(&s->options, "buffer-limit"); | ||||
| 	if (data->buffer == -1) { | ||||
| 		paste_add(&s->buffers, buf, limit); | ||||
| 		paste_add(&s->buffers, buf, sb.st_size, limit); | ||||
| 		return (0); | ||||
| 	} | ||||
| 	if (paste_replace(&s->buffers, data->buffer, buf) != 0) { | ||||
| 	if (paste_replace(&s->buffers, data->buffer, buf, sb.st_size) != 0) { | ||||
| 		ctx->error(ctx, "no buffer %d", data->buffer); | ||||
| 		xfree(buf); | ||||
| 		return (-1); | ||||
|   | ||||
| @@ -45,13 +45,13 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| { | ||||
| 	struct cmd_buffer_data	*data = self->data; | ||||
| 	struct winlink		*wl; | ||||
| 	struct window		*w; | ||||
| 	struct window_pane	*wp; | ||||
| 	struct session		*s; | ||||
| 	struct paste_buffer	*pb; | ||||
|  | ||||
| 	if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) | ||||
| 		return (-1); | ||||
| 	w = wl->window; | ||||
| 	wp = wl->window->active; | ||||
|  | ||||
| 	if (data->buffer == -1) | ||||
| 		pb = paste_get_top(&s->buffers); | ||||
| @@ -64,13 +64,10 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
|  | ||||
| 	if (pb != NULL && *pb->data != '\0') { | ||||
| 		/* -r means raw data without LF->CR conversion. */ | ||||
| 		if (data->chflags & CMD_CHFLAG('r')) { | ||||
| 			buffer_write( | ||||
| 			    w->active->out, pb->data, strlen(pb->data)); | ||||
| 		} else { | ||||
| 			cmd_paste_buffer_lf2cr( | ||||
| 			    w->active->out, pb->data, strlen(pb->data)); | ||||
| 		} | ||||
| 		if (data->chflags & CMD_CHFLAG('r')) | ||||
| 			buffer_write(wp->out, pb->data, pb->size); | ||||
| 		else | ||||
| 			cmd_paste_buffer_lf2cr(wp->out, pb->data, pb->size); | ||||
| 	} | ||||
|  | ||||
| 	/* Delete the buffer if -d. */ | ||||
|   | ||||
| @@ -75,7 +75,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| 		return (-1); | ||||
| 	} | ||||
|  | ||||
| 	if (fwrite(pb->data, 1, strlen(pb->data), f) != strlen(pb->data)) { | ||||
| 	if (fwrite(pb->data, 1, pb->size, f) != pb->size) { | ||||
| 	    	ctx->error(ctx, "%s: fwrite error", data->arg); | ||||
| 	    	fclose(f); | ||||
| 	    	return (-1); | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "tmux.h" | ||||
|  | ||||
| @@ -45,17 +45,23 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| 	struct cmd_buffer_data	*data = self->data; | ||||
| 	struct session		*s; | ||||
| 	u_int			 limit; | ||||
| 	u_char			*pdata; | ||||
| 	size_t			 psize; | ||||
|  | ||||
| 	if ((s = cmd_find_session(ctx, data->target)) == NULL) | ||||
| 		return (-1); | ||||
|  | ||||
| 	limit = options_get_number(&s->options, "buffer-limit"); | ||||
|  | ||||
| 	pdata = xstrdup(data->arg); | ||||
| 	psize = strlen(pdata); | ||||
|  | ||||
| 	if (data->buffer == -1) { | ||||
| 		paste_add(&s->buffers, xstrdup(data->arg), limit); | ||||
| 		paste_add(&s->buffers, pdata, psize, limit); | ||||
| 		return (0); | ||||
| 	} | ||||
| 	if (paste_replace(&s->buffers, data->buffer, xstrdup(data->arg)) != 0) { | ||||
| 	if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) { | ||||
| 		ctx->error(ctx, "no buffer %d", data->buffer); | ||||
| 		xfree(pdata); | ||||
| 		return (-1); | ||||
| 	} | ||||
| 	return (0); | ||||
|   | ||||
| @@ -18,7 +18,6 @@ | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
| #include <string.h> | ||||
| #include <vis.h> | ||||
|  | ||||
| #include "tmux.h" | ||||
| @@ -65,7 +64,7 @@ cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||
| 	if (pb == NULL) | ||||
| 		return (0); | ||||
|  | ||||
| 	size = strlen(pb->data); | ||||
| 	size = pb->size; | ||||
| 	if (size > SIZE_MAX / 4 - 1) | ||||
| 		size = SIZE_MAX / 4 - 1; | ||||
| 	in = xmalloc(size * 4 + 1); | ||||
|   | ||||
							
								
								
									
										6
									
								
								paste.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								paste.c
									
									
									
									
									
								
							| @@ -97,7 +97,7 @@ paste_free_index(struct paste_stack *ps, u_int idx) | ||||
| } | ||||
|  | ||||
| void | ||||
| paste_add(struct paste_stack *ps, char *data, u_int limit) | ||||
| paste_add(struct paste_stack *ps, u_char *data, size_t size, u_int limit) | ||||
| { | ||||
| 	struct paste_buffer	*pb; | ||||
|  | ||||
| @@ -115,12 +115,13 @@ paste_add(struct paste_stack *ps, char *data, u_int limit) | ||||
| 	ARRAY_INSERT(ps, 0, pb); | ||||
|  | ||||
| 	pb->data = data; | ||||
| 	pb->size = size; | ||||
| 	if (gettimeofday(&pb->tv, NULL) != 0) | ||||
| 		fatal("gettimeofday"); | ||||
| } | ||||
|  | ||||
| int | ||||
| paste_replace(struct paste_stack *ps, u_int idx, char *data) | ||||
| paste_replace(struct paste_stack *ps, u_int idx, u_char *data, size_t size) | ||||
| { | ||||
| 	struct paste_buffer	*pb; | ||||
|  | ||||
| @@ -131,6 +132,7 @@ paste_replace(struct paste_stack *ps, u_int idx, char *data) | ||||
| 	xfree(pb->data); | ||||
|  | ||||
| 	pb->data = data; | ||||
| 	pb->size = size; | ||||
| 	if (gettimeofday(&pb->tv, NULL) != 0) | ||||
| 		fatal("gettimeofday"); | ||||
|  | ||||
|   | ||||
							
								
								
									
										7
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								status.c
									
									
									
									
									
								
							| @@ -928,9 +928,10 @@ status_prompt_key(struct client *c, int key) | ||||
| 	case MODEKEYEDIT_PASTE: | ||||
| 		if ((pb = paste_get_top(&c->session->buffers)) == NULL) | ||||
| 			break; | ||||
| 		if ((last = strchr(pb->data, '\n')) == NULL) | ||||
| 			last = strchr(pb->data, '\0'); | ||||
| 		n = last - pb->data; | ||||
| 		for (n = 0; n < pb->size; n++) { | ||||
| 			if (pb->data[n] < 32 || pb->data[n] == 127) | ||||
| 				break; | ||||
| 		} | ||||
|  | ||||
| 		c->prompt_buffer = xrealloc(c->prompt_buffer, 1, size + n + 1); | ||||
| 		if (c->prompt_index == size) { | ||||
|   | ||||
							
								
								
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -772,6 +772,7 @@ struct layout_cell { | ||||
| /* Paste buffer. */ | ||||
| struct paste_buffer { | ||||
|      	char		*data; | ||||
| 	size_t		 size; | ||||
| 	struct timeval	 tv; | ||||
| }; | ||||
| ARRAY_DECL(paste_stack, struct paste_buffer *); | ||||
| @@ -1257,8 +1258,8 @@ struct paste_buffer *paste_get_top(struct paste_stack *); | ||||
| struct paste_buffer *paste_get_index(struct paste_stack *, u_int); | ||||
| int	     	 paste_free_top(struct paste_stack *); | ||||
| int		 paste_free_index(struct paste_stack *, u_int); | ||||
| void		 paste_add(struct paste_stack *, char *, u_int); | ||||
| int		 paste_replace(struct paste_stack *, u_int, char *); | ||||
| void		 paste_add(struct paste_stack *, u_char *, size_t, u_int); | ||||
| int		 paste_replace(struct paste_stack *, u_int, u_char *, size_t); | ||||
|  | ||||
| /* clock.c */ | ||||
| extern const char clock_table[14][5][5]; | ||||
|   | ||||
| @@ -849,13 +849,16 @@ window_copy_copy_selection(struct window_pane *wp, struct client *c) | ||||
| 		window_copy_copy_line(wp, &buf, &off, ey, 0, ex); | ||||
| 	} | ||||
|  | ||||
| 	/* Terminate buffer, overwriting final \n. */ | ||||
| 	if (off != 0) | ||||
| 		buf[off - 1] = '\0'; | ||||
| 	/* Don't bother if no data. */ | ||||
| 	if (off == 0) { | ||||
| 		xfree(buf); | ||||
| 		return; | ||||
| 	} | ||||
| 	off--;	/* remove final \n */ | ||||
|  | ||||
| 	/* Add the buffer to the stack. */ | ||||
| 	limit = options_get_number(&c->session->options, "buffer-limit"); | ||||
| 	paste_add(&c->session->buffers, buf, limit); | ||||
| 	paste_add(&c->session->buffers, buf, off, limit); | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott