aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/uudecode.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 751976a87..10e5a55de 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -286,13 +286,19 @@ int baseNUM_main(int argc UNUSED_PARAM, char **argv)
286 } else { 286 } else {
287 enum { 287 enum {
288 SRC_BUF_SIZE = 3 * 5 * 32, /* this *MUST* be a multiple of 3 and 5 */ 288 SRC_BUF_SIZE = 3 * 5 * 32, /* this *MUST* be a multiple of 3 and 5 */
289 DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3), 289 DST_BUF_SIZE = 8 * ((SRC_BUF_SIZE + 4) / 5), /* max growth on decode (base32 case) */
290 }; 290 };
291 char src_buf[SRC_BUF_SIZE]; 291 /* Use one buffer for both input and output:
292 char dst_buf[DST_BUF_SIZE + 1]; 292 * decoding reads input "left-to-right",
293 int src_fd = fileno(src_stream); 293 * it's safe to place source at the end of the buffer and
294 int rem = 0; 294 * overwrite it while decoding, just be careful to have a gap.
295 */
296 char dst_buf[((DST_BUF_SIZE + /*gap:*/ 16) /*round up to 16:*/ | 0xf) + 1];
297#define src_buf (dst_buf + sizeof(dst_buf) - SRC_BUF_SIZE)
298 int src_fd, rem;
295 299
300 src_fd = fileno(src_stream);
301 rem = 0;
296 while (1) { 302 while (1) {
297 size_t size = full_read(src_fd, src_buf, SRC_BUF_SIZE); 303 size_t size = full_read(src_fd, src_buf, SRC_BUF_SIZE);
298 if ((ssize_t)size < 0) 304 if ((ssize_t)size < 0)
@@ -331,6 +337,7 @@ int baseNUM_main(int argc UNUSED_PARAM, char **argv)
331 } 337 }
332 } 338 }
333 } 339 }
340#undef src_buf
334 } 341 }
335 342
336 fflush_stdout_and_exit(EXIT_SUCCESS); 343 fflush_stdout_and_exit(EXIT_SUCCESS);