# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: address@hidden # target_branch: bzr+ssh://address@hidden/emacs/trunk # testament_sha1: 3eeb60f5950d82650e3b759001afaed50f02f05d # timestamp: 2011-04-12 22:02:59 -0700 # base_revision_id: address@hidden # # Begin patch === modified file 'src/ChangeLog' --- src/ChangeLog 2011-04-12 10:20:32 +0000 +++ src/ChangeLog 2011-04-13 05:02:54 +0000 @@ -1,3 +1,27 @@ +2011-04-13 Paul Eggert + + emacs_write: Return size_t, not ssize_t, to avoid overflow issues. + * gnutls.c, gnutls.h (emacs_gnutls_write): Return size_t, not ssize_t. + * sysdep.c, lisp.h (emacs_write): Likewise. + Without the above change, emacs_gnutls_write and emacs_write had + undefined behavior and would typically mistakenly report an error + when writing a buffer whose size exceeds SSIZE_MAX. + (emacs_read, emacs_write): Remove check for negative size, as the + Emacs source code has been audited now. + (emacs_write): Adjust to new signature, making the code look more + like that of emacs_gnutls_write. + * process.c (send_process): Adjust to the new signatures of + emacs_write and emacs_gnutls_write. Do not attempt to store + a byte offset into an 'int'; it might overflow. + + * sound.c: Don't assume sizes fit in 'int'. + (struct sound_device.period_size, alsa_period_size): + Return size_t, not int. + (struct sound_device.write, vox_write, alsa_write): + Accept size_t, not int. + (wav_play, au_play): Use size_t to store sizes, and ssize_t to + record read return values. + 2011-04-12 Andreas Schwab * charset.c (Fclear_charset_maps): Use xfree instead of free. === modified file 'src/gnutls.c' --- src/gnutls.c 2011-04-10 14:00:13 +0000 +++ src/gnutls.c 2011-04-13 05:02:54 +0000 @@ -70,7 +70,7 @@ } } -ssize_t +size_t emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf, size_t nbyte) { @@ -85,7 +85,7 @@ #ifdef EAGAIN errno = EAGAIN; #endif - return -1; + return 0; } bytes_written = 0; @@ -99,7 +99,7 @@ if (rtnval == GNUTLS_E_AGAIN || rtnval == GNUTLS_E_INTERRUPTED) continue; else - return (bytes_written ? bytes_written : -1); + break; } buf += rtnval; === modified file 'src/gnutls.h' --- src/gnutls.h 2011-04-10 14:00:13 +0000 +++ src/gnutls.h 2011-04-13 05:02:54 +0000 @@ -50,7 +50,7 @@ #define GNUTLS_LOG2(level, max, string, extra) if (level <= max) { gnutls_log_function2 (level, "(Emacs) " string, extra); } -ssize_t +size_t emacs_gnutls_write (int fildes, struct Lisp_Process *proc, const char *buf, size_t nbyte); ssize_t === modified file 'src/lisp.h' --- src/lisp.h 2011-04-12 08:12:01 +0000 +++ src/lisp.h 2011-04-13 05:02:54 +0000 @@ -3347,7 +3347,7 @@ extern int emacs_open (const char *, int, int); extern int emacs_close (int); extern ssize_t emacs_read (int, char *, size_t); -extern ssize_t emacs_write (int, const char *, size_t); +extern size_t emacs_write (int, const char *, size_t); enum { READLINK_BUFSIZE = 1024 }; extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]); #ifndef HAVE_MEMSET === modified file 'src/process.c' --- src/process.c 2011-04-10 14:00:13 +0000 +++ src/process.c 2011-04-13 05:02:54 +0000 @@ -5367,6 +5367,7 @@ /* Send this batch, using one or more write calls. */ while (this > 0) { + size_t written = 0; int outfd = p->outfd; old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); #ifdef DATAGRAM_SOCKETS @@ -5375,7 +5376,9 @@ rv = sendto (outfd, buf, this, 0, datagram_address[outfd].sa, datagram_address[outfd].len); - if (rv < 0 && errno == EMSGSIZE) + if (0 <= rv) + written = rv; + else if (errno == EMSGSIZE) { signal (SIGPIPE, old_sigpipe); report_file_error ("sending datagram", @@ -5387,12 +5390,13 @@ { #ifdef HAVE_GNUTLS if (XPROCESS (proc)->gnutls_p) - rv = emacs_gnutls_write (outfd, - XPROCESS (proc), - buf, this); + written = emacs_gnutls_write (outfd, + XPROCESS (proc), + buf, this); else #endif - rv = emacs_write (outfd, buf, this); + written = emacs_write (outfd, buf, this); + rv = (written == this ? 0 : -1); #ifdef ADAPTIVE_READ_BUFFERING if (p->read_output_delay > 0 && p->adaptive_read_buffering == 1) @@ -5419,7 +5423,7 @@ that may allow the program to finish doing output and read more. */ { - int offset = 0; + size_t offset = 0; #ifdef BROKEN_PTY_READ_AFTER_EAGAIN /* A gross hack to work around a bug in FreeBSD. @@ -5465,16 +5469,14 @@ offset); else if (STRINGP (object)) buf = offset + SSDATA (object); - - rv = 0; } else /* This is a real error. */ report_file_error ("writing to process", Fcons (proc, Qnil)); } - buf += rv; - len -= rv; - this -= rv; + buf += written; + len -= written; + this -= written; } } } === modified file 'src/sound.c' --- src/sound.c 2011-04-12 10:20:32 +0000 +++ src/sound.c 2011-04-13 03:22:40 +0000 @@ -235,11 +235,11 @@ /* Return a preferred data size in bytes to be sent to write (below) each time. 2048 is used if this is NULL. */ - int (* period_size) (struct sound_device *sd); + size_t (* period_size) (struct sound_device *sd); /* Write NYBTES bytes from BUFFER to device SD. */ void (* write) (struct sound_device *sd, const char *buffer, - int nbytes); + size_t nbytes); /* A place for devices to store additional data. */ void *data; @@ -291,7 +291,7 @@ static void vox_close (struct sound_device *sd); static void vox_choose_format (struct sound_device *, struct sound *); static int vox_init (struct sound_device *); -static void vox_write (struct sound_device *, const char *, int); +static void vox_write (struct sound_device *, const char *, size_t); static void find_sound_type (struct sound *); static u_int32_t le2hl (u_int32_t); static u_int16_t le2hs (u_int16_t); @@ -600,9 +600,9 @@ else { char *buffer; - int nbytes = 0; - int blksize = sd->period_size ? sd->period_size (sd) : 2048; - int data_left = header->data_length; + ssize_t nbytes = 0; + size_t blksize = sd->period_size ? sd->period_size (sd) : 2048; + size_t data_left = header->data_length; buffer = (char *) alloca (blksize); lseek (s->fd, sizeof *header, SEEK_SET); @@ -690,9 +690,9 @@ SBYTES (s->data) - header->data_offset); else { - int blksize = sd->period_size ? sd->period_size (sd) : 2048; + size_t blksize = sd->period_size ? sd->period_size (sd) : 2048; char *buffer; - int nbytes; + ssize_t nbytes; /* Seek */ lseek (s->fd, header->data_offset, SEEK_SET); @@ -895,10 +895,9 @@ /* Write NBYTES bytes from BUFFER to device SD. */ static void -vox_write (struct sound_device *sd, const char *buffer, int nbytes) +vox_write (struct sound_device *sd, const char *buffer, size_t nbytes) { - ssize_t nwritten = emacs_write (sd->fd, buffer, nbytes); - if (nwritten < 0) + if (emacs_write (sd->fd, buffer, nbytes) != nbytes) sound_perror ("Error writing to sound device"); } @@ -953,7 +952,7 @@ alsa_sound_perror (file, err); } -static int +static size_t alsa_period_size (struct sound_device *sd) { struct alsa_params *p = (struct alsa_params *) sd->data; @@ -1156,13 +1155,13 @@ /* Write NBYTES bytes from BUFFER to device SD. */ static void -alsa_write (struct sound_device *sd, const char *buffer, int nbytes) +alsa_write (struct sound_device *sd, const char *buffer, size_t nbytes) { struct alsa_params *p = (struct alsa_params *) sd->data; /* The the third parameter to snd_pcm_writei is frames, not bytes. */ int fact = snd_pcm_format_size (sd->format, 1) * sd->channels; - int nwritten = 0; + size_t nwritten = 0; int err; while (nwritten < nbytes) === modified file 'src/sysdep.c' --- src/sysdep.c 2011-04-12 08:12:01 +0000 +++ src/sysdep.c 2011-04-13 05:02:54 +0000 @@ -1825,41 +1825,36 @@ return rtnval; } +/* Read from FILEDESC to a buffer BUF with size NBYTE, retrying if interrupted. + Return the number of bytes read, which might be less than NBYTE. + On error, set errno and return -1. */ ssize_t emacs_read (int fildes, char *buf, size_t nbyte) { register ssize_t rtnval; - /* Defend against the possibility that a buggy caller passes a negative NBYTE - argument, which would be converted to a large unsigned size_t NBYTE. This - defense prevents callers from doing large writes, unfortunately. This - size restriction can be removed once we have carefully checked that there - are no such callers. */ - if ((ssize_t) nbyte < 0) - abort (); - while ((rtnval = read (fildes, buf, nbyte)) == -1 && (errno == EINTR)) QUIT; return (rtnval); } -ssize_t +/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted + or if a partial write occurs. Return the number of bytes written, setting + errno if this is less than NBYTE. */ +size_t emacs_write (int fildes, const char *buf, size_t nbyte) { - register ssize_t rtnval, bytes_written; - - /* Defend against negative NBYTE, as in emacs_read. */ - if ((ssize_t) nbyte < 0) - abort (); + ssize_t rtnval; + size_t bytes_written; bytes_written = 0; - while (nbyte != 0) + while (nbyte > 0) { rtnval = write (fildes, buf, nbyte); - if (rtnval == -1) + if (rtnval < 0) { if (errno == EINTR) { @@ -1871,13 +1866,14 @@ continue; } else - return (bytes_written ? bytes_written : -1); + break; } buf += rtnval; nbyte -= rtnval; bytes_written += rtnval; } + return (bytes_written); } # Begin bundle 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