Now on revision 105662. ------------------------------------------------------------ revno: 105662 committer: Glenn Morris branch nick: trunk timestamp: Mon 2011-09-05 06:18:36 -0400 message: Auto-commit of generated files. diff: === modified file 'autogen/config.in' --- autogen/config.in 2011-08-14 10:19:49 +0000 +++ autogen/config.in 2011-09-05 10:18:36 +0000 @@ -672,6 +672,9 @@ /* Define to 1 if the system has the type `sigset_t'. */ #undef HAVE_SIGSET_T +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + /* Define to 1 if you have sound support. */ #undef HAVE_SOUND === modified file 'autogen/configure' --- autogen/configure 2011-08-31 10:18:35 +0000 +++ autogen/configure 2011-09-05 10:18:36 +0000 @@ -15312,6 +15312,18 @@ fi +for ac_func in snprintf +do : + ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" +if test "x$ac_cv_func_snprintf" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SNPRINTF 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 $as_echo_n "checking for nl_langinfo and CODESET... " >&6; } if test "${emacs_cv_langinfo_codeset+set}" = set; then : ------------------------------------------------------------ revno: 105661 fixes bug(s): http://debbugs.gnu.org/9414 author: Oleksandr Gavenko committer: Juri Linkov branch nick: trunk timestamp: Mon 2011-09-05 12:55:11 +0300 message: * lisp/progmodes/grep.el (rgrep): Add "-type d". diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-09-05 09:48:26 +0000 +++ lisp/ChangeLog 2011-09-05 09:55:11 +0000 @@ -1,3 +1,7 @@ +2011-09-05 Oleksandr Gavenko (tiny change) + + * progmodes/grep.el (rgrep): Add "-type d" (bug#9414). + 2011-09-05 Juri Linkov * progmodes/grep.el (grep-process-setup): Fix comments (bug#8084). === modified file 'lisp/progmodes/grep.el' --- lisp/progmodes/grep.el 2011-09-05 09:48:26 +0000 +++ lisp/progmodes/grep.el 2011-09-05 09:55:11 +0000 @@ -989,7 +989,8 @@ dir (concat (and grep-find-ignored-directories - (concat (shell-quote-argument "(") + (concat "-type d " + (shell-quote-argument "(") ;; we should use shell-quote-argument here " -path " (mapconcat ------------------------------------------------------------ revno: 105660 fixes bug(s): http://debbugs.gnu.org/8084 committer: Juri Linkov branch nick: trunk timestamp: Mon 2011-09-05 12:48:26 +0300 message: * lisp/progmodes/grep.el (grep-process-setup): Fix comments. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-09-05 08:20:02 +0000 +++ lisp/ChangeLog 2011-09-05 09:48:26 +0000 @@ -1,5 +1,9 @@ 2011-09-05 Juri Linkov + * progmodes/grep.el (grep-process-setup): Fix comments (bug#8084). + +2011-09-05 Juri Linkov + * progmodes/grep.el (grep-filter): Avoid incomplete processing by keeping point where processing of grep matches begins, and continue to delete remaining escape sequences from the same point. === modified file 'lisp/progmodes/grep.el' --- lisp/progmodes/grep.el 2011-09-05 08:20:02 +0000 +++ lisp/progmodes/grep.el 2011-09-05 09:48:26 +0000 @@ -446,9 +446,10 @@ (when (eq grep-highlight-matches 'auto-detect) (grep-compute-defaults)) (unless (or (eq grep-highlight-matches 'auto-detect) - ;; Uses font-lock to parse color escapes. (Bug#8084) - (null font-lock-mode) - (null grep-highlight-matches)) + (null grep-highlight-matches) + ;; Don't output color escapes if they can't be + ;; highlighted with `font-lock-face' by `grep-filter'. + (null font-lock-mode)) ;; `setenv' modifies `process-environment' let-bound in `compilation-start' ;; Any TERM except "dumb" allows GNU grep to use `--color=auto' (setenv "TERM" "emacs-grep") ------------------------------------------------------------ revno: 105659 committer: Michael Albinus branch nick: trunk timestamp: Mon 2011-09-05 11:34:18 +0200 message: * dbusbind.c (xd_signature_cat): Rename from signature_cat. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-09-04 19:18:28 +0000 +++ src/ChangeLog 2011-09-05 09:34:18 +0000 @@ -1,3 +1,7 @@ +2011-09-05 Michael Albinus + + * dbusbind.c (xd_signature_cat): Rename from signature_cat. + 2011-09-04 Paul Eggert sprintf-related integer and memory overflow issues (Bug#9412). === modified file 'src/dbusbind.c' --- src/dbusbind.c 2011-09-01 14:44:49 +0000 +++ src/dbusbind.c 2011-09-05 09:34:18 +0000 @@ -262,7 +262,7 @@ /* Append to SIGNATURE a copy of X, making sure SIGNATURE does not become too long. */ static void -signature_cat (char *signature, char const *x) +xd_signature_cat (char *signature, char const *x) { ptrdiff_t siglen = strlen (signature); ptrdiff_t xlen = strlen (x); @@ -401,10 +401,10 @@ { subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - signature_cat (signature, x); + xd_signature_cat (signature, x); elt = CDR_SAFE (XD_NEXT_VALUE (elt)); } - signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); + xd_signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); break; case DBUS_TYPE_DICT_ENTRY: @@ -425,7 +425,7 @@ elt = XD_NEXT_VALUE (elt); subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - signature_cat (signature, x); + xd_signature_cat (signature, x); if (!XD_BASIC_DBUS_TYPE (subtype)) wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt))); @@ -434,14 +434,14 @@ elt = CDR_SAFE (XD_NEXT_VALUE (elt)); subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - signature_cat (signature, x); + xd_signature_cat (signature, x); if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) wrong_type_argument (intern ("D-Bus"), CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt)))); /* Closing signature. */ - signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); + xd_signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); break; default: ------------------------------------------------------------ revno: 105658 fixes bug(s): http://debbugs.gnu.org/9408 committer: Juri Linkov branch nick: trunk timestamp: Mon 2011-09-05 11:20:02 +0300 message: Grep related fixes. * etc/grep.txt: Add `eval' to the Local Variables section that emulates `grep-filter'. * lisp/progmodes/grep.el (grep-filter): Avoid incomplete processing by keeping point where processing of grep matches begins, and continue to delete remaining escape sequences from the same point. (grep-filter): Make leading zero optional in "0?1;31m" because git-grep emits "\033[1;31m" escape sequences unlike expected "\033[01;31m" as GNU Grep does. (grep-process-setup): Replace obsolete "ml=" with newer "sl=". diff: === modified file 'etc/ChangeLog' --- etc/ChangeLog 2011-08-30 05:52:05 +0000 +++ etc/ChangeLog 2011-09-05 08:20:02 +0000 @@ -1,3 +1,8 @@ +2011-09-05 Juri Linkov + + * grep.txt: Add `eval' to the Local Variables section that + emulates `grep-filter'. + 2011-08-30 Paul Eggert * MACHINES: Remove obsolete info and update a bit (Bug#9404). === modified file 'etc/grep.txt' --- etc/grep.txt 2011-01-25 04:08:28 +0000 +++ etc/grep.txt 2011-09-05 08:20:02 +0000 @@ -103,5 +103,6 @@ ;;; Local Variables: +;;; eval: (let ((inhibit-read-only t) (compilation-filter-start (point-min))) (save-excursion (goto-char (point-max)) (grep-filter) (set-buffer-modified-p nil))) ;;; buffer-read-only: t ;;; End: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-09-05 08:05:01 +0000 +++ lisp/ChangeLog 2011-09-05 08:20:02 +0000 @@ -1,5 +1,15 @@ 2011-09-05 Juri Linkov + * progmodes/grep.el (grep-filter): Avoid incomplete processing by + keeping point where processing of grep matches begins, and + continue to delete remaining escape sequences from the same point. + (grep-filter): Make leading zero optional in "0?1;31m" because + git-grep emits "\033[1;31m" escape sequences unlike expected + "\033[01;31m" as GNU Grep does (bug#9408). + (grep-process-setup): Replace obsolete "ml=" with newer "sl=". + +2011-09-05 Juri Linkov + * subr.el (y-or-n-p): Capitalize "yes". 2011-09-04 Michael Albinus === modified file 'lisp/progmodes/grep.el' --- lisp/progmodes/grep.el 2011-08-22 09:54:38 +0000 +++ lisp/progmodes/grep.el 2011-09-05 08:20:02 +0000 @@ -459,7 +459,7 @@ ;; GREP_COLOR is used in GNU grep 2.5.1, but deprecated in later versions (setenv "GREP_COLOR" "01;31") ;; GREP_COLORS is used in GNU grep 2.5.2 and later versions - (setenv "GREP_COLORS" "mt=01;31:fn=:ln=:bn=:se=:ml=:cx=:ne")) + (setenv "GREP_COLORS" "mt=01;31:fn=:ln=:bn=:se=:sl=:cx=:ne")) (set (make-local-variable 'compilation-exit-message-function) (lambda (status code msg) (if (eq status 'exit) @@ -480,20 +480,21 @@ This function is called from `compilation-filter-hook'." (save-excursion (forward-line 0) - (let ((end (point))) + (let ((end (point)) beg) (goto-char compilation-filter-start) (forward-line 0) + (setq beg (point)) ;; Only operate on whole lines so we don't get caught with part of an ;; escape sequence in one chunk and the rest in another. (when (< (point) end) (setq end (copy-marker end)) ;; Highlight grep matches and delete marking sequences. - (while (re-search-forward "\033\\[01;31m\\(.*?\\)\033\\[[0-9]*m" end 1) + (while (re-search-forward "\033\\[0?1;31m\\(.*?\\)\033\\[[0-9]*m" end 1) (replace-match (propertize (match-string 1) 'face nil 'font-lock-face grep-match-face) t t)) ;; Delete all remaining escape sequences - (goto-char compilation-filter-start) + (goto-char beg) (while (re-search-forward "\033\\[[0-9;]*[mK]" end 1) (replace-match "" t t)))))) ------------------------------------------------------------ revno: 105657 committer: Juri Linkov branch nick: trunk timestamp: Mon 2011-09-05 11:05:01 +0300 message: * lisp/subr.el (y-or-n-p): Capitalize "yes". diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-09-04 18:14:34 +0000 +++ lisp/ChangeLog 2011-09-05 08:05:01 +0000 @@ -1,3 +1,7 @@ +2011-09-05 Juri Linkov + + * subr.el (y-or-n-p): Capitalize "yes". + 2011-09-04 Michael Albinus * net/tramp.el (top): Require 'shell. Use `tramp-unload-hook' but === modified file 'lisp/subr.el' --- lisp/subr.el 2011-08-30 14:50:02 +0000 +++ lisp/subr.el 2011-09-05 08:05:01 +0000 @@ -2254,7 +2254,7 @@ (listp last-nonmenu-event) use-dialog-box) (setq answer - (x-popup-dialog t `(,prompt ("yes" . act) ("No" . skip)))) + (x-popup-dialog t `(,prompt ("Yes" . act) ("No" . skip)))) (setq prompt (concat prompt (if (eq ?\s (aref prompt (1- (length prompt)))) "" " ") ------------------------------------------------------------ revno: 105656 author: Lars Magne Ingebrigtsen committer: Katsumi Yamaoka branch nick: trunk timestamp: Sun 2011-09-04 22:17:09 +0000 message: Merge changes made in Gnus trunk. gnus.el (gnus-home-directory): Add warning about setting in .gnus.el (bug#9405). gnus-score.el (gnus-summary-increase-score): Doc clarification (bug#9421). gnus-spec.el (gnus-face-0): Make all the face specs into defcustoms (bug#9425). gnus-art.el (gnus-treatment-function-alist): Remove CRs as the first thing (bug#9426). diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2011-09-03 22:51:26 +0000 +++ lisp/gnus/ChangeLog 2011-09-04 22:17:09 +0000 @@ -1,3 +1,17 @@ +2011-09-04 Lars Magne Ingebrigtsen + + * gnus.el (gnus-home-directory): Add warning about setting in .gnus.el + (bug#9405). + + * gnus-score.el (gnus-summary-increase-score): Doc clarification + (bug#9421). + + * gnus-spec.el (gnus-face-0): Make all the face specs into defcustoms + (bug#9425). + + * gnus-art.el (gnus-treatment-function-alist): Remove CRs as the first + thing (bug#9426). + 2011-09-03 Lars Magne Ingebrigtsen * nnimap.el (nnimap-open-connection-1): Use the correct port number in === modified file 'lisp/gnus/gnus-art.el' --- lisp/gnus/gnus-art.el 2011-08-21 22:10:49 +0000 +++ lisp/gnus/gnus-art.el 2011-09-04 22:17:09 +0000 @@ -1657,14 +1657,14 @@ (defvar gnus-article-mime-handle-alist-1 nil) (defvar gnus-treatment-function-alist - '((gnus-treat-x-pgp-sig gnus-article-verify-x-pgp-sig) + '((gnus-treat-strip-cr gnus-article-remove-cr) + (gnus-treat-x-pgp-sig gnus-article-verify-x-pgp-sig) (gnus-treat-strip-banner gnus-article-strip-banner) (gnus-treat-strip-headers-in-body gnus-article-strip-headers-in-body) (gnus-treat-highlight-signature gnus-article-highlight-signature) (gnus-treat-buttonize gnus-article-add-buttons) (gnus-treat-fill-article gnus-article-fill-cited-article) (gnus-treat-fill-long-lines gnus-article-fill-cited-long-lines) - (gnus-treat-strip-cr gnus-article-remove-cr) (gnus-treat-unsplit-urls gnus-article-unsplit-urls) (gnus-treat-display-x-face gnus-article-display-x-face) (gnus-treat-display-face gnus-article-display-face) === modified file 'lisp/gnus/gnus-score.el' --- lisp/gnus/gnus-score.el 2011-08-13 08:55:53 +0000 +++ lisp/gnus/gnus-score.el 2011-09-04 22:17:09 +0000 @@ -522,9 +522,10 @@ (defun gnus-summary-lower-score (&optional score symp) "Make a score entry based on the current article. The user will be prompted for header to score on, match type, -permanence, and the string to be used. The numerical prefix will be -used as score. A symbolic prefix of `a' says to use the `all.SCORE' -file for the command instead of the current score file." +permanence, and the string to be used. The numerical prefix will +be used as SCORE. A symbolic prefix of `a' (the SYMP parameter) +says to use the `all.SCORE' file for the command instead of the +current score file." (interactive (gnus-interactive "P\ny")) (gnus-summary-increase-score (- (gnus-score-delta-default score)) symp)) @@ -537,9 +538,10 @@ (defun gnus-summary-increase-score (&optional score symp) "Make a score entry based on the current article. The user will be prompted for header to score on, match type, -permanence, and the string to be used. The numerical prefix will be -used as score. A symbolic prefix of `a' says to use the `all.SCORE' -file for the command instead of the current score file." +permanence, and the string to be used. The numerical prefix will +be used as SCORE. A symbolic prefix of `a' (the SYMP parameter) +says to use the `all.SCORE' file for the command instead of the +current score file." (interactive (gnus-interactive "P\ny")) (let* ((nscore (gnus-score-delta-default score)) (prefix (if (< nscore 0) ?L ?I)) === modified file 'lisp/gnus/gnus-spec.el' --- lisp/gnus/gnus-spec.el 2011-08-18 22:12:47 +0000 +++ lisp/gnus/gnus-spec.el 2011-09-04 22:17:09 +0000 @@ -264,11 +264,30 @@ (push (cons 'version emacs-version) gnus-format-specs)) updated)) -(defvar gnus-mouse-face-0 'highlight) -(defvar gnus-mouse-face-1 'highlight) -(defvar gnus-mouse-face-2 'highlight) -(defvar gnus-mouse-face-3 'highlight) -(defvar gnus-mouse-face-4 'highlight) +(defcustom gnus-mouse-face-0 'highlight + "The \"%(hello%)\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-mouse-face-1 'highlight + "The \"%1(hello%)\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-mouse-face-2 'highlight + "The \"%2(hello%)\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-mouse-face-3 'highlight + "The \"%3(hello%)\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-mouse-face-4 'highlight + "The \"%4(hello%)\" face." + :group 'gnus-format + :type 'face) (defun gnus-mouse-face-function (form type) `(gnus-put-text-property @@ -278,11 +297,30 @@ 'gnus-mouse-face `(quote ,(symbol-value (intern (format "gnus-mouse-face-%d" type))))))) -(defvar gnus-face-0 'bold) -(defvar gnus-face-1 'italic) -(defvar gnus-face-2 'bold-italic) -(defvar gnus-face-3 'bold) -(defvar gnus-face-4 'bold) +(defcustom gnus-face-0 'bold + "The \"%{hello%}\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-face-1 'italic + "The \"%1{hello%}\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-face-2 'bold-italic + "The \"%2{hello%}\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-face-3 'bold + "The \"%3{hello%}\" face." + :group 'gnus-format + :type 'face) + +(defcustom gnus-face-4 'bold + "The \"%4{hello%}\" face." + :group 'gnus-format + :type 'face) (defun gnus-face-face-function (form type) `(gnus-add-text-properties === modified file 'lisp/gnus/gnus.el' --- lisp/gnus/gnus.el 2011-08-04 22:14:04 +0000 +++ lisp/gnus/gnus.el 2011-09-04 22:17:09 +0000 @@ -1245,7 +1245,12 @@ (defcustom gnus-home-directory "~/" "Directory variable that specifies the \"home\" directory. -All other Gnus file and directory variables are initialized from this variable." +All other Gnus file and directory variables are initialized from this variable. + +Note that Gnus is mostly loaded when the `.gnus.el' file is read. +This means that other directory variables that are initialized +from this variable won't be set properly if you set this variable +in `.gnus.el'. Set this variable in `.emacs' instead." :group 'gnus-files :type 'directory) ------------------------------------------------------------ revno: 105655 [merge] fixes bug(s): http://debbugs.gnu.org/9397 http://debbugs.gnu.org/9412 committer: Paul Eggert branch nick: trunk timestamp: Sun 2011-09-04 14:52:59 -0700 message: sprintf-related integer and memory overflow issues diff: === modified file 'ChangeLog' --- ChangeLog 2011-08-30 20:46:59 +0000 +++ ChangeLog 2011-09-04 21:52:59 +0000 @@ -1,3 +1,7 @@ +2011-09-04 Paul Eggert + + * configure.in (snprintf): New check. + 2011-08-30 Paul Eggert * configure.in (opsys): Change pattern to *-*-linux* === modified file 'configure.in' --- configure.in 2011-08-30 20:46:59 +0000 +++ configure.in 2011-08-31 22:18:16 +0000 @@ -3071,6 +3071,8 @@ AC_FUNC_FORK +AC_CHECK_FUNCS(snprintf) + dnl Adapted from Haible's version. AC_CACHE_CHECK([for nl_langinfo and CODESET], emacs_cv_langinfo_codeset, [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], === modified file 'lib-src/ChangeLog' --- lib-src/ChangeLog 2011-07-28 00:48:01 +0000 +++ lib-src/ChangeLog 2011-09-04 21:52:59 +0000 @@ -1,3 +1,38 @@ +2011-09-04 Paul Eggert + + Integer and memory overflow issues (Bug#9397). + + * emacsclient.c (xmalloc): Accept size_t, not unsigned int, to + avoid potential buffer overflow issues on typical 64-bit hosts. + Return void *, not long *. + (get_current_dir_name): Report a failure, instead of looping + forever, if buffer size calculation overflows. Treat malloc + failures like realloc failures, as that has better behavior and is + more consistent. Do not check whether xmalloc returns NULL, as + that's not possible. + (message): Do not arbitrarily truncate message to 2048 bytes when + sending it to stderr; use vfprintf instead. + (get_server_config, set_local_socket) + (start_daemon_and_retry_set_socket): Do not alloca + arbitrarily-large buffers; that's not safe. + (get_server_config, set_local_socket): Do not use sprintf when its + result might not fit in 'int'. + (set_local_socket): Do not assume uid fits in 'int'. + + * etags.c (xmalloc, xrealloc): Accept size_t, not unsigned int, + to avoid potential buffer overflow issues on typical 64-bit hosts. + (whatlen_max): New static var. + (main): Avoid buffer overflow if subsidiary command length is + greater than BUFSIZ or 2*BUFSIZ + 20. Do not use sprintf when its + result might not fit in 'int'. + + * movemail.c (main): Do not use sprintf when its result might not fit + in 'int'. Instead, put the possibly-long file name into the + output of pfatal_with_name. + + * update-game-score.c: Include + (get_user_id): Do not assume uid fits in 'int'. Simplify. + 2011-07-28 Paul Eggert Assume freestanding C89 headers, string.h, stdlib.h. === modified file 'lib-src/emacsclient.c' --- lib-src/emacsclient.c 2011-07-02 15:07:57 +0000 +++ lib-src/emacsclient.c 2011-08-28 23:52:34 +0000 @@ -194,10 +194,10 @@ /* Like malloc but get fatal error if memory is exhausted. */ -static long * -xmalloc (unsigned int size) +static void * +xmalloc (size_t size) { - long *result = (long *) malloc (size); + void *result = malloc (size); if (result == NULL) { perror ("malloc"); @@ -250,32 +250,33 @@ ) { buf = (char *) xmalloc (strlen (pwd) + 1); - if (!buf) - return NULL; strcpy (buf, pwd); } #ifdef HAVE_GETCWD else { size_t buf_size = 1024; - buf = (char *) xmalloc (buf_size); - if (!buf) - return NULL; for (;;) { + int tmp_errno; + buf = malloc (buf_size); + if (! buf) + break; if (getcwd (buf, buf_size) == buf) break; - if (errno != ERANGE) + tmp_errno = errno; + free (buf); + if (tmp_errno != ERANGE) { - int tmp_errno = errno; - free (buf); errno = tmp_errno; return NULL; } buf_size *= 2; - buf = (char *) realloc (buf, buf_size); - if (!buf) - return NULL; + if (! buf_size) + { + errno = ENOMEM; + return NULL; + } } } #else @@ -283,8 +284,6 @@ { /* We need MAXPATHLEN here. */ buf = (char *) xmalloc (MAXPATHLEN + 1); - if (!buf) - return NULL; if (getwd (buf) == NULL) { int tmp_errno = errno; @@ -494,16 +493,17 @@ static void message (int is_error, const char *format, ...) { - char msg[2048]; va_list args; va_start (args, format); - vsprintf (msg, format, args); - va_end (args); #ifdef WINDOWSNT if (w32_window_app ()) { + char msg[2048]; + vsnprintf (msg, sizeof msg, format, args); + msg[sizeof msg - 1] = '\0'; + if (is_error) MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR); else @@ -514,9 +514,11 @@ { FILE *f = is_error ? stderr : stdout; - fputs (msg, f); + vfprintf (f, format, args); fflush (f); } + + va_end (args); } /* Decode the options from argv and argc. @@ -959,18 +961,24 @@ if (home) { - char *path = alloca (strlen (home) + strlen (server_file) - + EXTRA_SPACE); - sprintf (path, "%s/.emacs.d/server/%s", home, server_file); + char *path = xmalloc (strlen (home) + strlen (server_file) + + EXTRA_SPACE); + strcpy (path, home); + strcat (path, "/.emacs.d/server/"); + strcat (path, server_file); config = fopen (path, "rb"); + free (path); } #ifdef WINDOWSNT if (!config && (home = egetenv ("APPDATA"))) { - char *path = alloca (strlen (home) + strlen (server_file) - + EXTRA_SPACE); - sprintf (path, "%s/.emacs.d/server/%s", home, server_file); + char *path = xmalloc (strlen (home) + strlen (server_file) + + EXTRA_SPACE); + strcpy (path, home); + strcat (path, "/.emacs.d/server/"); + strcat (path, server_file); config = fopen (path, "rb"); + free (path); } #endif } @@ -1243,6 +1251,8 @@ int saved_errno = 0; const char *server_name = "server"; const char *tmpdir IF_LINT ( = NULL); + char *tmpdir_storage = NULL; + char *socket_name_storage = NULL; if (socket_name && !strchr (socket_name, '/') && !strchr (socket_name, '\\')) @@ -1255,6 +1265,8 @@ if (default_sock) { + long uid = geteuid (); + ptrdiff_t tmpdirlen; tmpdir = egetenv ("TMPDIR"); if (!tmpdir) { @@ -1265,17 +1277,19 @@ size_t n = confstr (_CS_DARWIN_USER_TEMP_DIR, NULL, (size_t) 0); if (n > 0) { - tmpdir = alloca (n); + tmpdir = tmpdir_storage = xmalloc (n); confstr (_CS_DARWIN_USER_TEMP_DIR, tmpdir, n); } else #endif tmpdir = "/tmp"; } - socket_name = alloca (strlen (tmpdir) + strlen (server_name) - + EXTRA_SPACE); - sprintf (socket_name, "%s/emacs%d/%s", - tmpdir, (int) geteuid (), server_name); + tmpdirlen = strlen (tmpdir); + socket_name = socket_name_storage = + xmalloc (tmpdirlen + strlen (server_name) + EXTRA_SPACE); + strcpy (socket_name, tmpdir); + sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid); + strcat (socket_name + tmpdirlen, server_name); } if (strlen (socket_name) < sizeof (server.sun_path)) @@ -1309,10 +1323,13 @@ if (pw && (pw->pw_uid != geteuid ())) { /* We're running under su, apparently. */ - socket_name = alloca (strlen (tmpdir) + strlen (server_name) - + EXTRA_SPACE); - sprintf (socket_name, "%s/emacs%d/%s", - tmpdir, (int) pw->pw_uid, server_name); + long uid = pw->pw_uid; + ptrdiff_t tmpdirlen = strlen (tmpdir); + socket_name = xmalloc (tmpdirlen + strlen (server_name) + + EXTRA_SPACE); + strcpy (socket_name, tmpdir); + sprintf (socket_name + tmpdirlen, "/emacs%ld/", uid); + strcat (socket_name + tmpdirlen, server_name); if (strlen (socket_name) < sizeof (server.sun_path)) strcpy (server.sun_path, socket_name); @@ -1322,6 +1339,7 @@ progname, socket_name); exit (EXIT_FAILURE); } + free (socket_name); sock_status = socket_status (server.sun_path); saved_errno = errno; @@ -1331,6 +1349,9 @@ } } + free (socket_name_storage); + free (tmpdir_storage); + switch (sock_status) { case 1: @@ -1526,8 +1547,8 @@ { /* Pass --daemon=socket_name as argument. */ const char *deq = "--daemon="; - char *daemon_arg = alloca (strlen (deq) - + strlen (socket_name) + 1); + char *daemon_arg = xmalloc (strlen (deq) + + strlen (socket_name) + 1); strcpy (daemon_arg, deq); strcat (daemon_arg, socket_name); d_argv[1] = daemon_arg; === modified file 'lib-src/etags.c' --- lib-src/etags.c 2011-07-07 01:32:56 +0000 +++ lib-src/etags.c 2011-08-28 23:55:41 +0000 @@ -414,8 +414,8 @@ static void canonicalize_filename (char *); static void linebuffer_init (linebuffer *); static void linebuffer_setlen (linebuffer *, int); -static PTR xmalloc (unsigned int); -static PTR xrealloc (char *, unsigned int); +static PTR xmalloc (size_t); +static PTR xrealloc (char *, size_t); static char searchar = '/'; /* use /.../ searches */ @@ -425,6 +425,7 @@ static char *cwd; /* current working directory */ static char *tagfiledir; /* directory of tagfile */ static FILE *tagf; /* ioptr for tags file */ +static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */ static fdesc *fdhead; /* head of file description list */ static fdesc *curfdp; /* current file description */ @@ -1066,6 +1067,7 @@ int current_arg, file_count; linebuffer filename_lb; bool help_asked = FALSE; + ptrdiff_t len; char *optstring; int opt; @@ -1110,6 +1112,9 @@ /* This means that a file name has been seen. Record it. */ argbuffer[current_arg].arg_type = at_filename; argbuffer[current_arg].what = optarg; + len = strlen (optarg); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; ++file_count; break; @@ -1118,6 +1123,9 @@ /* Parse standard input. Idea by Vivek . */ argbuffer[current_arg].arg_type = at_stdin; argbuffer[current_arg].what = optarg; + len = strlen (optarg); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; ++file_count; if (parsing_stdin) @@ -1160,6 +1168,9 @@ case 'r': argbuffer[current_arg].arg_type = at_regexp; argbuffer[current_arg].what = optarg; + len = strlen (optarg); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; break; case 'R': @@ -1198,6 +1209,9 @@ { argbuffer[current_arg].arg_type = at_filename; argbuffer[current_arg].what = argv[optind]; + len = strlen (argv[optind]); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; ++file_count; } @@ -1331,7 +1345,9 @@ /* From here on, we are in (CTAGS && !cxref_style) */ if (update) { - char cmd[BUFSIZ]; + char *cmd = + xmalloc (strlen (tagfile) + whatlen_max + + sizeof "mv..OTAGS;fgrep -v '\t\t' OTAGS >;rm OTAGS"); for (i = 0; i < current_arg; ++i) { switch (argbuffer[i].arg_type) @@ -1342,12 +1358,17 @@ default: continue; /* the for loop */ } - sprintf (cmd, - "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", - tagfile, argbuffer[i].what, tagfile); + strcpy (cmd, "mv "); + strcat (cmd, tagfile); + strcat (cmd, " OTAGS;fgrep -v '\t"); + strcat (cmd, argbuffer[i].what); + strcat (cmd, "\t' OTAGS >"); + strcat (cmd, tagfile); + strcat (cmd, ";rm OTAGS"); if (system (cmd) != EXIT_SUCCESS) fatal ("failed to execute shell command", (char *)NULL); } + free (cmd); append_to_tagfile = TRUE; } @@ -1363,11 +1384,14 @@ if (CTAGS) if (append_to_tagfile || update) { - char cmd[2*BUFSIZ+20]; + char *cmd = xmalloc (2 * strlen (tagfile) + sizeof "sort -u -o.."); /* Maybe these should be used: setenv ("LC_COLLATE", "C", 1); setenv ("LC_ALL", "C", 1); */ - sprintf (cmd, "sort -u -o %.*s %.*s", BUFSIZ, tagfile, BUFSIZ, tagfile); + strcpy (cmd, "sort -u -o "); + strcat (cmd, tagfile); + strcat (cmd, " "); + strcat (cmd, tagfile); exit (system (cmd)); } return EXIT_SUCCESS; @@ -6656,7 +6680,7 @@ /* Like malloc but get fatal error if memory is exhausted. */ static PTR -xmalloc (unsigned int size) +xmalloc (size_t size) { PTR result = (PTR) malloc (size); if (result == NULL) @@ -6665,7 +6689,7 @@ } static PTR -xrealloc (char *ptr, unsigned int size) +xrealloc (char *ptr, size_t size) { PTR result = (PTR) realloc (ptr, size); if (result == NULL) === modified file 'lib-src/movemail.c' --- lib-src/movemail.c 2011-07-07 01:32:56 +0000 +++ lib-src/movemail.c 2011-08-28 23:57:19 +0000 @@ -325,11 +325,10 @@ if (desc < 0) { int mkstemp_errno = errno; - char *message = (char *) xmalloc (strlen (tempname) + 50); - sprintf (message, "creating %s, which would become the lock file", - tempname); + error ("error while creating what would become the lock file", + 0, 0); errno = mkstemp_errno; - pfatal_with_name (message); + pfatal_with_name (tempname); } close (desc); === modified file 'lib-src/update-game-score.c' --- lib-src/update-game-score.c 2011-07-11 06:05:57 +0000 +++ lib-src/update-game-score.c 2011-08-28 23:59:14 +0000 @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -128,19 +129,13 @@ static char * get_user_id (void) { - char *name; struct passwd *buf = getpwuid (getuid ()); if (!buf) { - int count = 1; - int uid = (int) getuid (); - int tuid = uid; - while (tuid /= 10) - count++; - name = malloc (count+1); - if (!name) - return NULL; - sprintf (name, "%d", uid); + long uid = getuid (); + char *name = malloc (sizeof uid * CHAR_BIT / 3 + 1); + if (name) + sprintf (name, "%ld", uid); return name; } return buf->pw_name; === modified file 'nt/ChangeLog' --- nt/ChangeLog 2011-07-28 00:48:01 +0000 +++ nt/ChangeLog 2011-09-04 21:52:59 +0000 @@ -1,3 +1,7 @@ +2011-09-04 Paul Eggert + + * config.nt (HAVE_SNPRINTF): New macro. + 2011-07-28 Paul Eggert Assume freestanding C89 headers, string.h, stdlib.h. === modified file 'nt/config.nt' --- nt/config.nt 2011-07-07 01:32:56 +0000 +++ nt/config.nt 2011-08-31 22:18:16 +0000 @@ -240,6 +240,7 @@ #define HAVE_SETSOCKOPT 1 #define HAVE_GETSOCKNAME 1 #define HAVE_GETPEERNAME 1 +#define HAVE_SNPRINTF 1 #define HAVE_LANGINFO_CODESET 1 /* Local (unix) sockets are not supported. */ #undef HAVE_SYS_UN_H === modified file 'src/ChangeLog' --- src/ChangeLog 2011-09-04 19:14:54 +0000 +++ src/ChangeLog 2011-09-04 19:18:28 +0000 @@ -1,15 +1,121 @@ 2011-09-04 Paul Eggert + sprintf-related integer and memory overflow issues (Bug#9412). + + * doprnt.c (doprnt): Support printing ptrdiff_t and intmax_t values. + (esprintf, exprintf, evxprintf): New functions. + * keyboard.c (command_loop_level): Now EMACS_INT, not int. + (cmd_error): kbd macro iterations count is now EMACS_INT, not int. + (modify_event_symbol): Do not assume that the length of + name_alist_or_stem is safe to alloca and fits in int. + (Fexecute_extended_command): Likewise for function name and binding. + (Frecursion_depth): Wrap around reliably on integer overflow. + * keymap.c (push_key_description): First arg is now EMACS_INT, not int, + since some callers pass EMACS_INT values. + (Fsingle_key_description): Don't crash if symbol name contains more + than MAX_ALLOCA bytes. + * minibuf.c (minibuf_level): Now EMACS_INT, not int. + (get_minibuffer): Arg is now EMACS_INT, not int. + * lisp.h (get_minibuffer, push_key_description): Reflect API changes. + (esprintf, exprintf, evxprintf): New decls. + * window.h (command_loop_level, minibuf_level): Reflect API changes. + + * dbusbind.c (signature_cat): New function. + (xd_signature, Fdbus_register_signal): + Do not overrun buffer; instead, report string overflow. + + * dispnew.c (add_window_display_history): Don't overrun buffer. + Truncate instead; this is OK since it's just a log. + + * editfns.c (Fcurrent_time_zone): Don't overrun buffer + even if the time zone offset is outlandishly large. + Don't mishandle offset == INT_MIN. + + * emacs.c (main) [NS_IMPL_COCOA]: Don't overrun buffer + when creating daemon; the previous buffer-overflow check was incorrect. + + * eval.c (verror): Simplify by rewriting in terms of evxprintf, + which has the guts of the old verror function. + + * filelock.c (lock_file_1, lock_file): Don't blindly alloca long name; + use SAFE_ALLOCA instead. Use esprintf to avoid int-overflow issues. + + * font.c: Include , for DBL_MAX_10_EXP. + (font_unparse_xlfd): Don't blindly alloca long strings. + Don't assume XINT result fits in int, or that XFLOAT_DATA * 10 + fits in int, when using sprintf. Use single snprintf to count + length of string rather than counting it via multiple sprintfs; + that's simpler and more reliable. + (font_unparse_fcname): Use it to avoid sprintf buffer overrun. + (generate_otf_features) [0 && HAVE_LIBOTF]: Use esprintf, not + sprintf, in case result does not fit in int. + + * fontset.c (num_auto_fontsets): Now printmax_t, not int. + (fontset_from_font): Print it. + + * frame.c (tty_frame_count): Now printmax_t, not int. + (make_terminal_frame, set_term_frame_name): Print it. + (x_report_frame_params): In X, window IDs are unsigned long, + not signed long, so print them as unsigned. + (validate_x_resource_name): Check for implausibly long names, + and don't assume name length fits in 'int'. + (x_get_resource_string): Don't blindly alloca invocation name; + use SAFE_ALLOCA. Use esprintf, not sprintf, in case result does + not fit in int. + + * gtkutil.c: Include , for DBL_MAX_10_EXP. + (xg_check_special_colors, xg_set_geometry): + Make sprintf buffers a bit bigger, to avoid potential buffer overrun. + + * lread.c (dir_warning): Don't blindly alloca buffer; use SAFE_ALLOCA. + Use esprintf, not sprintf, in case result does not fit in int. + + * macros.c (executing_kbd_macro_iterations): Now EMACS_INT, not int. + (Fend_kbd_macro): Don't mishandle MOST_NEGATIVE_FIXNUM by treating + it as a large positive number. + (Fexecute_kbd_macro): Don't assume repeat count fits in int. + * macros.h (executing_kbd_macro_iterations): Now EMACS_INT, not int. + + * nsterm.m ((NSSize)windowWillResize): Use esprintf, not sprintf, + in case result does not fit in int. + + * print.c (float_to_string): Detect width overflow more reliably. + (print_object): Make sprintf buffer a bit bigger, to avoid potential + buffer overrun. Don't assume list length fits in 'int'. Treat + print length of 0 as 0, not as infinity; to be consistent with other + uses of print length in this function. Don't overflow print length + index. Don't assume hash table size fits in 'long', or that + vectorlike size fits in 'unsigned long'. + + * process.c (make_process): Use printmax_t, not int, to format + process-name gensyms. + + * sysdep.c (snprintf) [! HAVE_SNPRINTF]: New function. + + * term.c (produce_glyphless_glyph): Make sprintf buffer a bit bigger + to avoid potential buffer overrun. + + * xfaces.c (x_update_menu_appearance): Don't overrun buffer + if X resource line is longer than 512 bytes. + + * xfns.c (x_window): Make sprintf buffer a bit bigger + to avoid potential buffer overrun. + + * xterm.c (x_io_error_quitter): Don't overrun sprintf buffer. + + * xterm.h (x_check_errors): Add ATTRIBUTE_FORMAT_PRINTF. + +2011-09-04 Paul Eggert + Integer overflow fixes for scrolling, etc. - Without this fix, Emacs silently mishandles large integers sometimes. - For example, "C-u 4294967297 M-x recenter" was be treated as if + Without these, Emacs silently mishandles large integers sometimes. + For example, "C-u 4294967297 M-x recenter" was treated as if it were "C-u 1 M-x recenter" on a typical 64-bit host. - * xdisp.c: Integer overflow fix. - (try_window_id): Check Emacs fixnum range before converting to 'int'. + * xdisp.c (try_window_id): Check Emacs fixnum range before + converting to 'int'. - * window.c: Integer overflow fixes. - (window_scroll_line_based, Frecenter): + * window.c (window_scroll_line_based, Frecenter): Check that an Emacs fixnum is in range before assigning it to 'int'. (Frecenter, Fmove_to_window_line): Use EMACS_INT, not int, for values converted from Emacs fixnums. @@ -18,18 +124,15 @@ (Fset_window_configuration, compare_window_configurations): Use ptrdiff_t, not int, for index that might exceed 2 GiB. - * search.c: Integer overflow fixes - (Freplace_match): Use ptrdiff_t, not int, for indexes that can - exceed INT_MAX. Check that EMACS_INT value is in range before - assigning it to the (possibly-narrower) index. + * search.c (Freplace_match): Use ptrdiff_t, not int, for indexes + that can exceed INT_MAX. Check that EMACS_INT value is in range + before assigning it to the (possibly-narrower) index. (match_limit): Don't assume that a fixnum can fit in 'int'. - * print.c: Integer overflow fix. - (print_object): Use ptrdiff_t, not int, for index that can + * print.c (print_object): Use ptrdiff_t, not int, for index that can exceed INT_MAX. - * indent.c: Integer overflow fixes. - (position_indentation): Now takes ptrdiff_t, not int. + * indent.c (position_indentation): Now takes ptrdiff_t, not int. (Fvertical_motion): Don't wrap around LINES values that don't fit in 'int'. Instead, treat them as extreme values. This is good enough for windows, which can't have more than INT_MAX lines anyway. === modified file 'src/dbusbind.c' --- src/dbusbind.c 2011-06-24 21:25:22 +0000 +++ src/dbusbind.c 2011-09-01 14:44:49 +0000 @@ -259,6 +259,18 @@ } \ while (0) +/* Append to SIGNATURE a copy of X, making sure SIGNATURE does + not become too long. */ +static void +signature_cat (char *signature, char const *x) +{ + ptrdiff_t siglen = strlen (signature); + ptrdiff_t xlen = strlen (x); + if (DBUS_MAXIMUM_SIGNATURE_LENGTH - xlen <= siglen) + string_overflow (); + strcat (signature, x); +} + /* Compute SIGNATURE of OBJECT. It must have a form that it can be used in dbus_message_iter_open_container. DTYPE is the DBusType the object is related to. It is passed as argument, because it @@ -271,6 +283,8 @@ { unsigned int subtype; Lisp_Object elt; + char const *subsig; + int subsiglen; char x[DBUS_MAXIMUM_SIGNATURE_LENGTH]; elt = object; @@ -328,12 +342,13 @@ if (NILP (elt)) { subtype = DBUS_TYPE_STRING; - strcpy (x, DBUS_TYPE_STRING_AS_STRING); + subsig = DBUS_TYPE_STRING_AS_STRING; } else { subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); + subsig = x; } /* If the element type is DBUS_TYPE_SIGNATURE, and this is the @@ -342,7 +357,7 @@ if ((subtype == DBUS_TYPE_SIGNATURE) && STRINGP (CAR_SAFE (XD_NEXT_VALUE (elt))) && NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) - strcpy (x, SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt)))); + subsig = SSDATA (CAR_SAFE (XD_NEXT_VALUE (elt))); while (!NILP (elt)) { @@ -351,7 +366,10 @@ elt = CDR_SAFE (XD_NEXT_VALUE (elt)); } - sprintf (signature, "%c%s", dtype, x); + subsiglen = snprintf (signature, DBUS_MAXIMUM_SIGNATURE_LENGTH, + "%c%s", dtype, subsig); + if (! (0 <= subsiglen && subsiglen < DBUS_MAXIMUM_SIGNATURE_LENGTH)) + string_overflow (); break; case DBUS_TYPE_VARIANT: @@ -383,10 +401,10 @@ { subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - strcat (signature, x); + signature_cat (signature, x); elt = CDR_SAFE (XD_NEXT_VALUE (elt)); } - strcat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); + signature_cat (signature, DBUS_STRUCT_END_CHAR_AS_STRING); break; case DBUS_TYPE_DICT_ENTRY: @@ -407,7 +425,7 @@ elt = XD_NEXT_VALUE (elt); subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - strcat (signature, x); + signature_cat (signature, x); if (!XD_BASIC_DBUS_TYPE (subtype)) wrong_type_argument (intern ("D-Bus"), CAR_SAFE (XD_NEXT_VALUE (elt))); @@ -416,14 +434,14 @@ elt = CDR_SAFE (XD_NEXT_VALUE (elt)); subtype = XD_OBJECT_TO_DBUS_TYPE (CAR_SAFE (elt)); xd_signature (x, subtype, dtype, CAR_SAFE (XD_NEXT_VALUE (elt))); - strcat (signature, x); + signature_cat (signature, x); if (!NILP (CDR_SAFE (XD_NEXT_VALUE (elt)))) wrong_type_argument (intern ("D-Bus"), CAR_SAFE (CDR_SAFE (XD_NEXT_VALUE (elt)))); /* Closing signature. */ - strcat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); + signature_cat (signature, DBUS_DICT_ENTRY_END_CHAR_AS_STRING); break; default: @@ -2026,7 +2044,7 @@ DBusConnection *connection; ptrdiff_t i; char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; - char x[DBUS_MAXIMUM_MATCH_RULE_LENGTH]; + int rulelen; DBusError derror; /* Check parameters. */ @@ -2071,32 +2089,43 @@ connection = xd_initialize (bus, TRUE); /* Create a rule to receive related signals. */ - sprintf (rule, - "type='signal',interface='%s',member='%s'", - SDATA (interface), - SDATA (signal)); + rulelen = snprintf (rule, sizeof rule, + "type='signal',interface='%s',member='%s'", + SDATA (interface), + SDATA (signal)); + if (! (0 <= rulelen && rulelen < sizeof rule)) + string_overflow (); /* Add unique name and path to the rule if they are non-nil. */ if (!NILP (uname)) { - sprintf (x, ",sender='%s'", SDATA (uname)); - strcat (rule, x); + int len = snprintf (rule + rulelen, sizeof rule - rulelen, + ",sender='%s'", SDATA (uname)); + if (! (0 <= len && len < sizeof rule - rulelen)) + string_overflow (); + rulelen += len; } if (!NILP (path)) { - sprintf (x, ",path='%s'", SDATA (path)); - strcat (rule, x); + int len = snprintf (rule + rulelen, sizeof rule - rulelen, + ",path='%s'", SDATA (path)); + if (! (0 <= len && len < sizeof rule - rulelen)) + string_overflow (); + rulelen += len; } /* Add arguments to the rule if they are non-nil. */ for (i = 6; i < nargs; ++i) if (!NILP (args[i])) { + int len; CHECK_STRING (args[i]); - sprintf (x, ",arg%"pD"d='%s'", i - 6, - SDATA (args[i])); - strcat (rule, x); + len = snprintf (rule + rulelen, sizeof rule - rulelen, + ",arg%"pD"d='%s'", i - 6, SDATA (args[i])); + if (! (0 <= len && len < sizeof rule - rulelen)) + string_overflow (); + rulelen += len; } /* Add the rule to the bus. */ === modified file 'src/dispnew.c' --- src/dispnew.c 2011-08-24 21:20:36 +0000 +++ src/dispnew.c 2011-09-01 14:44:49 +0000 @@ -272,15 +272,16 @@ buf = redisplay_history[history_idx].trace; ++history_idx; - sprintf (buf, "%"pMu": window %p (`%s')%s\n", - history_tick++, - w, - ((BUFFERP (w->buffer) - && STRINGP (BVAR (XBUFFER (w->buffer), name))) - ? SSDATA (BVAR (XBUFFER (w->buffer), name)) - : "???"), - paused_p ? " ***paused***" : ""); - strcat (buf, msg); + snprintf (buf, sizeof redisplay_history[0].trace, + "%"pMu": window %p (`%s')%s\n%s", + history_tick++, + w, + ((BUFFERP (w->buffer) + && STRINGP (BVAR (XBUFFER (w->buffer), name))) + ? SSDATA (BVAR (XBUFFER (w->buffer), name)) + : "???"), + paused_p ? " ***paused***" : "", + msg); } === modified file 'src/doprnt.c' --- src/doprnt.c 2011-07-07 02:14:52 +0000 +++ src/doprnt.c 2011-09-01 14:44:49 +0000 @@ -70,9 +70,9 @@ %character where flags is [+ -0], width is [0-9]+, precision is .[0-9]+, and length - is empty or l or the value of the pI macro. Also, %% in a format - stands for a single % in the output. A % that does not introduce a - valid %-sequence causes undefined behavior. + is empty or l or the value of the pD or pI or pMd (sans "d") macros. + Also, %% in a format stands for a single % in the output. A % that + does not introduce a valid %-sequence causes undefined behavior. The + flag character inserts a + before any positive number, while a space inserts a space before any positive number; these flags only affect %d, %o, @@ -85,8 +85,10 @@ modifier: it is supported for %d, %o, and %x conversions of integral arguments, must immediately precede the conversion specifier, and means that the respective argument is to be treated as `long int' or `unsigned long - int'. Similarly, the value of the pI macro means to use EMACS_INT or - EMACS_UINT and the empty length modifier means `int' or `unsigned int'. + int'. Similarly, the value of the pD macro means to use ptrdiff_t, + the value of the pI macro means to use EMACS_INT or EMACS_UINT, the + value of the pMd etc. macros means to use intmax_t or uintmax_t, + and the empty length modifier means `int' or `unsigned int'. The width specifier supplies a lower limit for the length of the printed representation. The padding, if any, normally goes on the left, but it goes @@ -173,8 +175,17 @@ { ptrdiff_t size_bound = 0; EMACS_INT width; /* Columns occupied by STRING on display. */ - int long_flag = 0; - int pIlen = sizeof pI - 1; + enum { + pDlen = sizeof pD - 1, + pIlen = sizeof pI - 1, + pMlen = sizeof pMd - 2 + }; + enum { + no_modifier, long_modifier, pD_modifier, pI_modifier, pM_modifier + } length_modifier = no_modifier; + static char const modifier_len[] = { 0, 1, pDlen, pIlen, pMlen }; + int maxmlen = max (max (1, pDlen), max (pIlen, pMlen)); + int mlen; fmt++; /* Copy this one %-spec into fmtcpy. */ @@ -213,19 +224,26 @@ fmt++; } - if (0 < pIlen && pIlen <= format_end - fmt - && memcmp (fmt, pI, pIlen) == 0) - { - long_flag = 2; - memcpy (string, fmt + 1, pIlen); - string += pIlen; - fmt += pIlen; - } - else if (fmt < format_end && *fmt == 'l') - { - long_flag = 1; - *string++ = *++fmt; - } + /* Check for the length modifiers in textual length order, so + that longer modifiers override shorter ones. */ + for (mlen = 1; mlen <= maxmlen; mlen++) + { + if (format_end - fmt < mlen) + break; + if (mlen == 1 && *fmt == 'l') + length_modifier = long_modifier; + if (mlen == pDlen && memcmp (fmt, pD, pDlen) == 0) + length_modifier = pD_modifier; + if (mlen == pIlen && memcmp (fmt, pI, pIlen) == 0) + length_modifier = pI_modifier; + if (mlen == pMlen && memcmp (fmt, pMd, pMlen) == 0) + length_modifier = pM_modifier; + } + + mlen = modifier_len[length_modifier]; + memcpy (string, fmt + 1, mlen); + string += mlen; + fmt += mlen; *string = 0; /* Make the size bound large enough to handle floating point formats @@ -252,55 +270,78 @@ /* case 'b': */ case 'l': case 'd': - { - int i; - long l; - - if (1 < long_flag) - { - EMACS_INT ll = va_arg (ap, EMACS_INT); - sprintf (sprintf_buffer, fmtcpy, ll); - } - else if (long_flag) - { - l = va_arg(ap, long); - sprintf (sprintf_buffer, fmtcpy, l); - } - else - { - i = va_arg(ap, int); - sprintf (sprintf_buffer, fmtcpy, i); - } - /* Now copy into final output, truncating as necessary. */ - string = sprintf_buffer; - goto doit; - } + switch (length_modifier) + { + case no_modifier: + { + int v = va_arg (ap, int); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case long_modifier: + { + long v = va_arg (ap, long); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pD_modifier: + signed_pD_modifier: + { + ptrdiff_t v = va_arg (ap, ptrdiff_t); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pI_modifier: + { + EMACS_INT v = va_arg (ap, EMACS_INT); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pM_modifier: + { + intmax_t v = va_arg (ap, intmax_t); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + } + /* Now copy into final output, truncating as necessary. */ + string = sprintf_buffer; + goto doit; case 'o': case 'x': - { - unsigned u; - unsigned long ul; - - if (1 < long_flag) - { - EMACS_UINT ull = va_arg (ap, EMACS_UINT); - sprintf (sprintf_buffer, fmtcpy, ull); - } - else if (long_flag) - { - ul = va_arg(ap, unsigned long); - sprintf (sprintf_buffer, fmtcpy, ul); - } - else - { - u = va_arg(ap, unsigned); - sprintf (sprintf_buffer, fmtcpy, u); - } - /* Now copy into final output, truncating as necessary. */ - string = sprintf_buffer; - goto doit; - } + switch (length_modifier) + { + case no_modifier: + { + unsigned v = va_arg (ap, unsigned); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case long_modifier: + { + unsigned long v = va_arg (ap, unsigned long); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pD_modifier: + goto signed_pD_modifier; + case pI_modifier: + { + EMACS_UINT v = va_arg (ap, EMACS_UINT); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + case pM_modifier: + { + uintmax_t v = va_arg (ap, uintmax_t); + sprintf (sprintf_buffer, fmtcpy, v); + } + break; + } + /* Now copy into final output, truncating as necessary. */ + string = sprintf_buffer; + goto doit; case 'f': case 'e': @@ -426,3 +467,61 @@ SAFE_FREE (); return bufptr - buffer; } + +/* Format to an unbounded buffer BUF. This is like sprintf, except it + is not limited to returning an 'int' so it doesn't have a silly 2 + GiB limit on typical 64-bit hosts. However, it is limited to the + Emacs-style formats that doprnt supports. + + Return the number of bytes put into BUF, excluding the terminating + '\0'. */ +ptrdiff_t +esprintf (char *buf, char const *format, ...) +{ + ptrdiff_t nbytes; + va_list ap; + va_start (ap, format); + nbytes = doprnt (buf, TYPE_MAXIMUM (ptrdiff_t), format, 0, ap); + va_end (ap); + return nbytes; +} + +/* Format to buffer *BUF of positive size *BUFSIZE, reallocating *BUF + and updating *BUFSIZE if the buffer is too small, and otherwise + behaving line esprintf. When reallocating, free *BUF unless it is + equal to NONHEAPBUF, and if BUFSIZE_MAX is nonnegative then signal + memory exhaustion instead of growing the buffer size past + BUFSIZE_MAX. */ +ptrdiff_t +exprintf (char **buf, ptrdiff_t *bufsize, + char const *nonheapbuf, ptrdiff_t bufsize_max, + char const *format, ...) +{ + ptrdiff_t nbytes; + va_list ap; + va_start (ap, format); + nbytes = evxprintf (buf, bufsize, nonheapbuf, bufsize_max, format, ap); + va_end (ap); + return nbytes; +} + +/* Act like exprintf, except take a va_list. */ +ptrdiff_t +evxprintf (char **buf, ptrdiff_t *bufsize, + char const *nonheapbuf, ptrdiff_t bufsize_max, + char const *format, va_list ap) +{ + for (;;) + { + ptrdiff_t nbytes; + va_list ap_copy; + va_copy (ap_copy, ap); + nbytes = doprnt (*buf, *bufsize, format, 0, ap_copy); + va_end (ap_copy); + if (nbytes < *bufsize - 1) + return nbytes; + if (*buf != nonheapbuf) + xfree (*buf); + *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); + } +} === modified file 'src/editfns.c' --- src/editfns.c 2011-08-19 06:11:38 +0000 +++ src/editfns.c 2011-08-29 15:53:21 +0000 @@ -2014,7 +2014,7 @@ { int offset = tm_diff (t, &gmt); char *s = 0; - char buf[6]; + char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; #ifdef HAVE_TM_ZONE if (t->tm_zone) @@ -2029,7 +2029,8 @@ if (!s) { /* No local time zone name is available; use "+-NNNN" instead. */ - int am = (offset < 0 ? -offset : offset) / 60; + int m = offset / 60; + int am = offset < 0 ? - m : m; sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60); s = buf; } === modified file 'src/emacs.c' --- src/emacs.c 2011-09-03 22:20:00 +0000 +++ src/emacs.c 2011-09-04 19:18:28 +0000 @@ -1072,15 +1072,17 @@ if (!dname_arg || !strchr (dname_arg, '\n')) { /* In orig, child: now exec w/special daemon name. */ char fdStr[80]; + int fdStrlen = + snprintf (fdStr, sizeof fdStr, + "--daemon=\n%d,%d\n%s", daemon_pipe[0], + daemon_pipe[1], dname_arg ? dname_arg : ""); - if (dname_arg && strlen (dname_arg) > 70) + if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr)) { fprintf (stderr, "daemon: child name too long\n"); exit (1); } - sprintf (fdStr, "--daemon=\n%d,%d\n%s", daemon_pipe[0], - daemon_pipe[1], dname_arg ? dname_arg : ""); argv[skip_args] = fdStr; execv (argv[0], argv); === modified file 'src/eval.c' --- src/eval.c 2011-08-24 21:20:36 +0000 +++ src/eval.c 2011-08-29 16:01:33 +0000 @@ -1951,35 +1951,11 @@ char buf[4000]; ptrdiff_t size = sizeof buf; ptrdiff_t size_max = STRING_BYTES_BOUND + 1; - char const *m_end = m + strlen (m); char *buffer = buf; ptrdiff_t used; Lisp_Object string; - while (1) - { - va_list ap_copy; - va_copy (ap_copy, ap); - used = doprnt (buffer, size, m, m_end, ap_copy); - va_end (ap_copy); - - /* Note: the -1 below is because `doprnt' returns the number of bytes - excluding the terminating null byte, and it always terminates with a - null byte, even when producing a truncated message. */ - if (used < size - 1) - break; - if (size <= size_max / 2) - size *= 2; - else if (size < size_max) - size = size_max; - else - break; /* and leave the message truncated */ - - if (buffer != buf) - xfree (buffer); - buffer = (char *) xmalloc (size); - } - + used = evxprintf (&buffer, &size, buf, size_max, m, ap); string = make_string (buffer, used); if (buffer != buf) xfree (buffer); === modified file 'src/filelock.c' --- src/filelock.c 2011-07-07 21:52:44 +0000 +++ src/filelock.c 2011-08-29 16:48:19 +0000 @@ -341,6 +341,9 @@ const char *user_name; const char *host_name; char *lock_info_str; + ptrdiff_t lock_info_size; + int symlink_errno; + USE_SAFE_ALLOCA; /* Call this first because it can GC. */ boot = get_boot_time (); @@ -353,17 +356,14 @@ host_name = SSDATA (Fsystem_name ()); else host_name = ""; - lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name) - + 2 * INT_STRLEN_BOUND (printmax_t) - + sizeof "@.:"); + lock_info_size = (strlen (user_name) + strlen (host_name) + + 2 * INT_STRLEN_BOUND (printmax_t) + + sizeof "@.:"); + SAFE_ALLOCA (lock_info_str, char *, lock_info_size); pid = getpid (); - if (boot) - sprintf (lock_info_str, "%s@%s.%"pMd":%"pMd, - user_name, host_name, pid, boot); - else - sprintf (lock_info_str, "%s@%s.%"pMd, - user_name, host_name, pid); + esprintf (lock_info_str, boot ? "%s@%s.%"pMd":%"pMd : "%s@%s.%"pMd, + user_name, host_name, pid, boot); err = symlink (lock_info_str, lfname); if (errno == EEXIST && force) @@ -372,6 +372,9 @@ err = symlink (lock_info_str, lfname); } + symlink_errno = errno; + SAFE_FREE (); + errno = symlink_errno; return err == 0; } @@ -541,9 +544,11 @@ { register Lisp_Object attack, orig_fn, encoded_fn; register char *lfname, *locker; + ptrdiff_t locker_size; lock_info_type lock_info; printmax_t pid; struct gcpro gcpro1; + USE_SAFE_ALLOCA; /* Don't do locking while dumping Emacs. Uncompressing wtmp files uses call-process, which does not work @@ -580,15 +585,17 @@ return; /* Else consider breaking the lock */ - locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host) - + INT_STRLEN_BOUND (printmax_t) - + sizeof "@ (pid )"); + locker_size = (strlen (lock_info.user) + strlen (lock_info.host) + + INT_STRLEN_BOUND (printmax_t) + + sizeof "@ (pid )"); + SAFE_ALLOCA (locker, char *, locker_size); pid = lock_info.pid; - sprintf (locker, "%s@%s (pid %"pMd")", - lock_info.user, lock_info.host, pid); + esprintf (locker, "%s@%s (pid %"pMd")", + lock_info.user, lock_info.host, pid); FREE_LOCK_INFO (lock_info); attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker)); + SAFE_FREE (); if (!NILP (attack)) /* User says take the lock */ { === modified file 'src/font.c' --- src/font.c 2011-07-10 08:20:10 +0000 +++ src/font.c 2011-09-01 14:44:49 +0000 @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see . */ #include +#include #include #include #include @@ -1180,7 +1181,7 @@ char *p; const char *f[XLFD_REGISTRY_INDEX + 1]; Lisp_Object val; - int i, j, len = 0; + int i, j, len; font_assert (FONTP (font)); @@ -1195,9 +1196,9 @@ if (NILP (val)) { if (j == XLFD_REGISTRY_INDEX) - f[j] = "*-*", len += 4; + f[j] = "*-*"; else - f[j] = "*", len += 2; + f[j] = "*"; } else { @@ -1207,21 +1208,15 @@ && ! strchr (SSDATA (val), '-')) { /* Change "jisx0208*" and "jisx0208" to "jisx0208*-*". */ - if (SDATA (val)[SBYTES (val) - 1] == '*') - { - f[j] = p = alloca (SBYTES (val) + 3); - sprintf (p, "%s-*", SDATA (val)); - len += SBYTES (val) + 3; - } - else - { - f[j] = p = alloca (SBYTES (val) + 4); - sprintf (p, "%s*-*", SDATA (val)); - len += SBYTES (val) + 4; - } + ptrdiff_t alloc = SBYTES (val) + 4; + if (nbytes <= alloc) + return -1; + f[j] = p = alloca (alloc); + sprintf (p, "%s%s-*", SDATA (val), + "*" + (SDATA (val)[SBYTES (val) - 1] == '*')); } else - f[j] = SSDATA (val), len += SBYTES (val) + 1; + f[j] = SSDATA (val); } } @@ -1230,11 +1225,11 @@ { val = font_style_symbolic (font, i, 0); if (NILP (val)) - f[j] = "*", len += 2; + f[j] = "*"; else { val = SYMBOL_NAME (val); - f[j] = SSDATA (val), len += SBYTES (val) + 1; + f[j] = SSDATA (val); } } @@ -1242,64 +1237,62 @@ font_assert (NUMBERP (val) || NILP (val)); if (INTEGERP (val)) { - i = XINT (val); - if (i <= 0) - i = pixel_size; - if (i > 0) + EMACS_INT v = XINT (val); + if (v <= 0) + v = pixel_size; + if (v > 0) { - f[XLFD_PIXEL_INDEX] = p = alloca (22); - len += sprintf (p, "%d-*", i) + 1; + f[XLFD_PIXEL_INDEX] = p = + alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT)); + sprintf (p, "%"pI"d-*", v); } else - f[XLFD_PIXEL_INDEX] = "*-*", len += 4; + f[XLFD_PIXEL_INDEX] = "*-*"; } else if (FLOATP (val)) { - i = XFLOAT_DATA (val) * 10; - f[XLFD_PIXEL_INDEX] = p = alloca (12); - len += sprintf (p, "*-%d", i) + 1; + double v = XFLOAT_DATA (val) * 10; + f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1); + sprintf (p, "*-%.0f", v); } else - f[XLFD_PIXEL_INDEX] = "*-*", len += 4; + f[XLFD_PIXEL_INDEX] = "*-*"; if (INTEGERP (AREF (font, FONT_DPI_INDEX))) { - i = XINT (AREF (font, FONT_DPI_INDEX)); - f[XLFD_RESX_INDEX] = p = alloca (22); - len += sprintf (p, "%d-%d", i, i) + 1; + EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX)); + f[XLFD_RESX_INDEX] = p = + alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT)); + sprintf (p, "%"pI"d-%"pI"d", v, v); } else - f[XLFD_RESX_INDEX] = "*-*", len += 4; + f[XLFD_RESX_INDEX] = "*-*"; if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) { - int spacing = XINT (AREF (font, FONT_SPACING_INDEX)); + EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX)); f[XLFD_SPACING_INDEX] = (spacing <= FONT_SPACING_PROPORTIONAL ? "p" : spacing <= FONT_SPACING_DUAL ? "d" : spacing <= FONT_SPACING_MONO ? "m" : "c"); - len += 2; } else - f[XLFD_SPACING_INDEX] = "*", len += 2; + f[XLFD_SPACING_INDEX] = "*"; if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) { - f[XLFD_AVGWIDTH_INDEX] = p = alloca (22); - len += sprintf (p, "%"pI"d", - XINT (AREF (font, FONT_AVGWIDTH_INDEX))) + 1; + f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT)); + sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX))); } else - f[XLFD_AVGWIDTH_INDEX] = "*", len += 2; - len++; /* for terminating '\0'. */ - if (len >= nbytes) - return -1; - return sprintf (name, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", + f[XLFD_AVGWIDTH_INDEX] = "*"; + len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX], f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX], f[XLFD_SWIDTH_INDEX], f[XLFD_ADSTYLE_INDEX], f[XLFD_PIXEL_INDEX], f[XLFD_RESX_INDEX], f[XLFD_SPACING_INDEX], f[XLFD_AVGWIDTH_INDEX], f[XLFD_REGISTRY_INDEX]); + return len < nbytes ? len : -1; } /* Parse NAME (null terminated) and store information in FONT @@ -1553,23 +1546,19 @@ font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int nbytes) { Lisp_Object family, foundry; - Lisp_Object tail, val; + Lisp_Object val; int point_size; int i; - ptrdiff_t len = 1; char *p; + char *lim; Lisp_Object styles[3]; const char *style_names[3] = { "weight", "slant", "width" }; - char work[256]; family = AREF (font, FONT_FAMILY_INDEX); if (! NILP (family)) { if (SYMBOLP (family)) - { - family = SYMBOL_NAME (family); - len += SBYTES (family); - } + family = SYMBOL_NAME (family); else family = Qnil; } @@ -1580,7 +1569,6 @@ if (XINT (val) != 0) pixel_size = XINT (val); point_size = -1; - len += 21; /* for ":pixelsize=NUM" */ } else { @@ -1588,80 +1576,91 @@ abort (); pixel_size = -1; point_size = (int) XFLOAT_DATA (val); - len += 11; /* for "-NUM" */ } foundry = AREF (font, FONT_FOUNDRY_INDEX); if (! NILP (foundry)) { if (SYMBOLP (foundry)) - { - foundry = SYMBOL_NAME (foundry); - len += 9 + SBYTES (foundry); /* ":foundry=NAME" */ - } + foundry = SYMBOL_NAME (foundry); else foundry = Qnil; } for (i = 0; i < 3; i++) - { - styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0); - if (! NILP (styles[i])) - len += sprintf (work, ":%s=%s", style_names[i], - SDATA (SYMBOL_NAME (styles[i]))); - } - - if (INTEGERP (AREF (font, FONT_DPI_INDEX))) - len += sprintf (work, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX))); - if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) - len += strlen (":spacing=100"); - if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) - len += strlen (":scalable=false"); /* or ":scalable=true" */ - for (tail = AREF (font, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) - { - Lisp_Object key = XCAR (XCAR (tail)), value = XCDR (XCAR (tail)); - - len += SBYTES (SYMBOL_NAME (key)) + 1; /* for :KEY= */ - if (STRINGP (value)) - len += SBYTES (value); - else if (INTEGERP (value)) - len += sprintf (work, "%"pI"d", XINT (value)); - else if (SYMBOLP (value)) - len += (NILP (value) ? 5 : 4); /* for "false" or "true" */ - } - - if (len > nbytes) - return -1; + styles[i] = font_style_symbolic (font, FONT_WEIGHT_INDEX + i, 0); + p = name; + lim = name + nbytes; if (! NILP (family)) - p += sprintf (p, "%s", SDATA (family)); + { + int len = snprintf (p, lim - p, "%s", SSDATA (family)); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; + } if (point_size > 0) { - if (p == name) - p += sprintf (p, "%d", point_size); - else - p += sprintf (p, "-%d", point_size); + int len = snprintf (p, lim - p, "-%d" + (p == name), point_size); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; } else if (pixel_size > 0) - p += sprintf (p, ":pixelsize=%d", pixel_size); + { + int len = snprintf (p, lim - p, ":pixelsize=%d", pixel_size); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; + } if (! NILP (AREF (font, FONT_FOUNDRY_INDEX))) - p += sprintf (p, ":foundry=%s", - SDATA (SYMBOL_NAME (AREF (font, FONT_FOUNDRY_INDEX)))); + { + int len = snprintf (p, lim - p, ":foundry=%s", + SSDATA (SYMBOL_NAME (AREF (font, + FONT_FOUNDRY_INDEX)))); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; + } for (i = 0; i < 3; i++) if (! NILP (styles[i])) - p += sprintf (p, ":%s=%s", style_names[i], - SDATA (SYMBOL_NAME (styles[i]))); + { + int len = snprintf (p, lim - p, ":%s=%s", style_names[i], + SSDATA (SYMBOL_NAME (styles[i]))); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; + } + if (INTEGERP (AREF (font, FONT_DPI_INDEX))) - p += sprintf (p, ":dpi=%"pI"d", XINT (AREF (font, FONT_DPI_INDEX))); + { + int len = snprintf (p, lim - p, ":dpi=%"pI"d", + XINT (AREF (font, FONT_DPI_INDEX))); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; + } + if (INTEGERP (AREF (font, FONT_SPACING_INDEX))) - p += sprintf (p, ":spacing=%"pI"d", XINT (AREF (font, FONT_SPACING_INDEX))); + { + int len = snprintf (p, lim - p, ":spacing=%"pI"d", + XINT (AREF (font, FONT_SPACING_INDEX))); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; + } + if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX))) { - if (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0) - p += sprintf (p, ":scalable=true"); - else - p += sprintf (p, ":scalable=false"); + int len = snprintf (p, lim - p, + (XINT (AREF (font, FONT_AVGWIDTH_INDEX)) == 0 + ? ":scalable=true" + : ":scalable=false")); + if (! (0 <= len && len < lim - p)) + return -1; + p += len; } + return (p - name); } @@ -1952,12 +1951,12 @@ else if (! asterisk) { val = SYMBOL_NAME (val); - p += sprintf (p, "%s", SDATA (val)); + p += esprintf (p, "%s", SDATA (val)); } else { val = SYMBOL_NAME (val); - p += sprintf (p, "~%s", SDATA (val)); + p += esprintf (p, "~%s", SDATA (val)); } } if (CONSP (spec)) === modified file 'src/fontset.c' --- src/fontset.c 2011-08-09 22:13:11 +0000 +++ src/fontset.c 2011-08-29 18:48:24 +0000 @@ -1700,7 +1700,7 @@ static Lisp_Object auto_fontset_alist; /* Number of automatically created fontsets. */ -static int num_auto_fontsets; +static printmax_t num_auto_fontsets; /* Retun a fontset synthesized from FONT-OBJECT. This is called from x_new_font when FONT-OBJECT is used for the default ASCII font of a @@ -1727,9 +1727,9 @@ alias = intern ("fontset-startup"); else { - char temp[32]; + char temp[sizeof "fontset-auto" + INT_STRLEN_BOUND (printmax_t)]; - sprintf (temp, "fontset-auto%d", num_auto_fontsets - 1); + sprintf (temp, "fontset-auto%"pMd, num_auto_fontsets - 1); alias = intern (temp); } fontset_spec = copy_font_spec (font_spec); === modified file 'src/frame.c' --- src/frame.c 2011-08-14 06:40:45 +0000 +++ src/frame.c 2011-08-29 18:52:26 +0000 @@ -497,7 +497,7 @@ /* Construct a frame that refers to a terminal. */ -static int tty_frame_count; +static printmax_t tty_frame_count; struct frame * make_initial_frame (void) @@ -551,7 +551,7 @@ { register struct frame *f; Lisp_Object frame; - char name[20]; + char name[sizeof "F" + INT_STRLEN_BOUND (printmax_t)]; if (!terminal->name) error ("Terminal is not live, can't create new frames on it"); @@ -562,7 +562,7 @@ Vframe_list = Fcons (frame, Vframe_list); tty_frame_count++; - sprintf (name, "F%d", tty_frame_count); + sprintf (name, "F%"pMd, tty_frame_count); f->name = build_string (name); f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */ @@ -2074,7 +2074,7 @@ /* If NAME is nil, set the name to F. */ if (NILP (name)) { - char namebuf[20]; + char namebuf[sizeof "F" + INT_STRLEN_BOUND (printmax_t)]; /* Check for no change needed in this very common case before we do any consing. */ @@ -2083,7 +2083,7 @@ return; tty_frame_count++; - sprintf (namebuf, "F%d", tty_frame_count); + sprintf (namebuf, "F%"pMd, tty_frame_count); name = build_string (namebuf); } else @@ -3065,6 +3065,7 @@ { char buf[16]; Lisp_Object tem; + unsigned long w; /* Represent negative positions (off the top or left screen edge) in a way that Fmodify_frame_parameters will understand correctly. */ @@ -3097,7 +3098,8 @@ for non-toolkit scroll bar. ruler-mode.el depends on this. */ : Qnil)); - sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f)); + w = FRAME_X_WINDOW (f); + sprintf (buf, "%lu", w); store_in_alist (alistptr, Qwindow_id, build_string (buf)); #ifdef HAVE_X_WINDOWS @@ -3105,7 +3107,10 @@ /* Tooltip frame may not have this widget. */ if (FRAME_X_OUTPUT (f)->widget) #endif - sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f)); + { + w = FRAME_OUTER_WINDOW (f); + sprintf (buf, "%lu", w); + } store_in_alist (alistptr, Qouter_window_id, build_string (buf)); #endif @@ -3576,13 +3581,13 @@ void validate_x_resource_name (void) { - int len = 0; + ptrdiff_t len = 0; /* Number of valid characters in the resource name. */ - int good_count = 0; + ptrdiff_t good_count = 0; /* Number of invalid characters in the resource name. */ - int bad_count = 0; + ptrdiff_t bad_count = 0; Lisp_Object new; - int i; + ptrdiff_t i; if (!STRINGP (Vx_resource_class)) Vx_resource_class = build_string (EMACS_CLASS); @@ -3615,8 +3620,9 @@ if (bad_count == 0) return; - /* If name is entirely invalid, or nearly so, use `emacs'. */ - if (good_count < 2) + /* If name is entirely invalid, or nearly so, or is so implausibly + large that alloca might not work, use `emacs'. */ + if (good_count < 2 || MAX_ALLOCA - sizeof ".customization" < len) { Vx_resource_name = build_string ("emacs"); return; @@ -3745,20 +3751,24 @@ { char *name_key; char *class_key; + char *result; struct frame *sf = SELECTED_FRAME (); + ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name); + USE_SAFE_ALLOCA; /* Allocate space for the components, the dots which separate them, and the final '\0'. */ - name_key = (char *) alloca (SBYTES (Vinvocation_name) - + strlen (attribute) + 2); + SAFE_ALLOCA (name_key, char *, invocation_namelen + strlen (attribute) + 2); class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2); - sprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); + esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute); sprintf (class_key, "%s.%s", EMACS_CLASS, class); - return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, - name_key, class_key); + result = x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb, + name_key, class_key); + SAFE_FREE (); + return result; } #endif === modified file 'src/gtkutil.c' --- src/gtkutil.c 2011-08-05 02:19:34 +0000 +++ src/gtkutil.c 2011-08-29 20:57:42 +0000 @@ -20,6 +20,7 @@ #include #ifdef USE_GTK +#include #include #include #include @@ -567,7 +568,7 @@ GtkStyleContext *gsty = gtk_widget_get_style_context (FRAME_GTK_OUTER_WIDGET (f)); GdkRGBA col; - char buf[64]; + char buf[sizeof "rgbi://" + 3 * (DBL_MAX_10_EXP + sizeof "-1.000000" - 1)]; int state = GTK_STATE_FLAG_SELECTED|GTK_STATE_FLAG_FOCUSED; if (get_fg) gtk_style_context_get_color (gsty, state, &col); @@ -797,7 +798,7 @@ int xneg = f->size_hint_flags & XNegative; int top = f->top_pos; int yneg = f->size_hint_flags & YNegative; - char geom_str[32]; + char geom_str[sizeof "=x--" + 4 * INT_STRLEN_BOUND (int)]; if (xneg) left = -left; === modified file 'src/keyboard.c' --- src/keyboard.c 2011-08-30 22:43:43 +0000 +++ src/keyboard.c 2011-08-31 20:02:51 +0000 @@ -196,7 +196,7 @@ int quit_char; /* Current depth in recursive edits. */ -int command_loop_level; +EMACS_INT command_loop_level; /* If not Qnil, this is a switch-frame event which we decided to put off until the end of a key sequence. This should be read as the @@ -998,7 +998,8 @@ cmd_error (Lisp_Object data) { Lisp_Object old_level, old_length; - char macroerror[50]; + char macroerror[sizeof "After..kbd macro iterations: " + + INT_STRLEN_BOUND (EMACS_INT)]; #ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) @@ -1010,7 +1011,7 @@ if (executing_kbd_macro_iterations == 1) sprintf (macroerror, "After 1 kbd macro iteration: "); else - sprintf (macroerror, "After %d kbd macro iterations: ", + sprintf (macroerror, "After %"pI"d kbd macro iterations: ", executing_kbd_macro_iterations); } else @@ -6463,11 +6464,15 @@ value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem)); else if (STRINGP (name_alist_or_stem)) { - int len = SBYTES (name_alist_or_stem); - char *buf = (char *) alloca (len + 50); - sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem), - XINT (symbol_int) + 1); + char *buf; + ptrdiff_t len = (SBYTES (name_alist_or_stem) + + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT)); + USE_SAFE_ALLOCA; + SAFE_ALLOCA (buf, char *, len); + esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem), + XINT (symbol_int) + 1); value = intern (buf); + SAFE_FREE (); } else if (name_table != 0 && name_table[symbol_num]) value = intern (name_table[symbol_num]); @@ -6483,7 +6488,7 @@ if (NILP (value)) { - char buf[20]; + char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)]; sprintf (buf, "key-%"pI"d", symbol_num); value = intern (buf); } @@ -10382,19 +10387,21 @@ char *newmessage; int message_p = push_message (); int count = SPECPDL_INDEX (); + ptrdiff_t newmessage_len, newmessage_alloc; + USE_SAFE_ALLOCA; record_unwind_protect (pop_message_unwind, Qnil); binding = Fkey_description (bindings, Qnil); - - newmessage - = (char *) alloca (SCHARS (SYMBOL_NAME (function)) - + SBYTES (binding) - + 100); - sprintf (newmessage, "You can run the command `%s' with %s", - SDATA (SYMBOL_NAME (function)), - SDATA (binding)); + newmessage_alloc = + (sizeof "You can run the command `' with " + + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding)); + SAFE_ALLOCA (newmessage, char *, newmessage_alloc); + newmessage_len = + esprintf (newmessage, "You can run the command `%s' with %s", + SDATA (SYMBOL_NAME (function)), + SDATA (binding)); message2 (newmessage, - strlen (newmessage), + newmessage_len, STRING_MULTIBYTE (binding)); if (NUMBERP (Vsuggest_key_bindings)) waited = sit_for (Vsuggest_key_bindings, 0, 2); @@ -10404,6 +10411,7 @@ if (!NILP (waited) && message_p) restore_message (); + SAFE_FREE (); unbind_to (count, Qnil); } } @@ -10633,7 +10641,9 @@ (void) { Lisp_Object temp; - XSETFASTINT (temp, command_loop_level + minibuf_level); + /* Wrap around reliably on integer overflow. */ + EMACS_INT sum = (command_loop_level & INTMASK) + (minibuf_level & INTMASK); + XSETINT (temp, sum); return temp; } === modified file 'src/keymap.c' --- src/keymap.c 2011-08-14 06:40:45 +0000 +++ src/keymap.c 2011-08-29 15:43:34 +0000 @@ -2143,12 +2143,12 @@ char * -push_key_description (register unsigned int c, register char *p, int force_multibyte) +push_key_description (EMACS_INT ch, char *p, int force_multibyte) { - unsigned c2; + int c, c2; /* Clear all the meaningless bits above the meta bit. */ - c &= meta_modifier | ~ - meta_modifier; + c = ch & (meta_modifier | ~ - meta_modifier); c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier | meta_modifier | shift_modifier | super_modifier); @@ -2283,10 +2283,15 @@ { if (NILP (no_angles)) { - char *buffer - = (char *) alloca (SBYTES (SYMBOL_NAME (key)) + 5); - sprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); - return build_string (buffer); + char *buffer; + Lisp_Object result; + USE_SAFE_ALLOCA; + SAFE_ALLOCA (buffer, char *, + sizeof "<>" + SBYTES (SYMBOL_NAME (key))); + esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); + result = build_string (buffer); + SAFE_FREE (); + return result; } else return Fsymbol_name (key); === modified file 'src/lisp.h' --- src/lisp.h 2011-08-14 06:40:45 +0000 +++ src/lisp.h 2011-09-01 14:44:49 +0000 @@ -2895,6 +2895,14 @@ /* Defined in doprnt.c */ extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *, va_list); +extern ptrdiff_t esprintf (char *, char const *, ...) + ATTRIBUTE_FORMAT_PRINTF (2, 3); +extern ptrdiff_t exprintf (char **, ptrdiff_t *, char const *, ptrdiff_t, + char const *, ...) + ATTRIBUTE_FORMAT_PRINTF (5, 6); +extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char const *, ptrdiff_t, + char const *, va_list) + ATTRIBUTE_FORMAT_PRINTF (5, 0); /* Defined in lread.c. */ extern Lisp_Object Qvariable_documentation, Qstandard_input; @@ -3186,7 +3194,7 @@ EXFUN (Feval_minibuffer, 2); EXFUN (Fread_string, 5); EXFUN (Fassoc_string, 3); -extern Lisp_Object get_minibuffer (int); +extern Lisp_Object get_minibuffer (EMACS_INT); extern void init_minibuf_once (void); extern void syms_of_minibuf (void); @@ -3250,7 +3258,7 @@ extern void init_keyboard (void); extern void syms_of_keyboard (void); extern void keys_of_keyboard (void); -extern char *push_key_description (unsigned int, char *, int); +extern char *push_key_description (EMACS_INT, char *, int); /* Defined in indent.c */ === modified file 'src/lread.c' --- src/lread.c 2011-08-18 08:41:19 +0000 +++ src/lread.c 2011-08-29 18:55:58 +0000 @@ -4295,14 +4295,20 @@ void dir_warning (const char *format, Lisp_Object dirname) { - char *buffer - = (char *) alloca (SCHARS (dirname) + strlen (format) + 5); - fprintf (stderr, format, SDATA (dirname)); - sprintf (buffer, format, SDATA (dirname)); + /* Don't log the warning before we've initialized!! */ if (initialized) - message_dolog (buffer, strlen (buffer), 0, STRING_MULTIBYTE (dirname)); + { + char *buffer; + ptrdiff_t message_len; + USE_SAFE_ALLOCA; + SAFE_ALLOCA (buffer, char *, + SBYTES (dirname) + strlen (format) - (sizeof "%s" - 1) + 1); + message_len = esprintf (buffer, format, SDATA (dirname)); + message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname)); + SAFE_FREE (); + } } void === modified file 'src/macros.c' --- src/macros.c 2011-07-29 01:00:29 +0000 +++ src/macros.c 2011-08-29 19:07:18 +0000 @@ -35,7 +35,7 @@ This is not bound at each level, so after an error, it describes the innermost interrupted macro. */ -int executing_kbd_macro_iterations; +EMACS_INT executing_kbd_macro_iterations; /* This is the macro that was executing. This is not bound at each level, @@ -175,11 +175,11 @@ if (XFASTINT (repeat) == 0) Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc); - else + else if (XINT (repeat) > 1) { XSETINT (repeat, XINT (repeat)-1); - if (XINT (repeat) > 0) - Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), repeat, loopfunc); + Fexecute_kbd_macro (KVAR (current_kboard, Vlast_kbd_macro), + repeat, loopfunc); } return Qnil; } @@ -302,9 +302,9 @@ Lisp_Object final; Lisp_Object tem; int pdlcount = SPECPDL_INDEX (); - int repeat = 1; + EMACS_INT repeat = 1; struct gcpro gcpro1, gcpro2; - int success_count = 0; + EMACS_INT success_count = 0; executing_kbd_macro_iterations = 0; === modified file 'src/macros.h' --- src/macros.h 2011-01-25 04:08:28 +0000 +++ src/macros.h 2011-08-29 19:07:18 +0000 @@ -22,7 +22,7 @@ This is not bound at each level, so after an error, it describes the innermost interrupted macro. */ -extern int executing_kbd_macro_iterations; +extern EMACS_INT executing_kbd_macro_iterations; /* This is the macro that was executing. This is not bound at each level, @@ -42,4 +42,3 @@ /* Store a character into kbd macro being defined */ extern void store_kbd_macro_char (Lisp_Object); - === modified file 'src/minibuf.c' --- src/minibuf.c 2011-08-05 02:15:35 +0000 +++ src/minibuf.c 2011-08-29 15:43:34 +0000 @@ -49,7 +49,7 @@ /* Depth in minibuffer invocations. */ -int minibuf_level; +EMACS_INT minibuf_level; /* The maximum length of a minibuffer history. */ @@ -772,10 +772,10 @@ used for nonrecursive minibuffer invocations. */ Lisp_Object -get_minibuffer (int depth) +get_minibuffer (EMACS_INT depth) { Lisp_Object tail, num, buf; - char name[24]; + char name[sizeof " *Minibuf-*" + INT_STRLEN_BOUND (EMACS_INT)]; XSETFASTINT (num, depth); tail = Fnthcdr (num, Vminibuffer_list); @@ -787,7 +787,7 @@ buf = Fcar (tail); if (NILP (buf) || NILP (BVAR (XBUFFER (buf), name))) { - sprintf (name, " *Minibuf-%d*", depth); + sprintf (name, " *Minibuf-%"pI"d*", depth); buf = Fget_buffer_create (build_string (name)); /* Although the buffer's name starts with a space, undo should be === modified file 'src/nsterm.m' --- src/nsterm.m 2011-08-15 05:30:45 +0000 +++ src/nsterm.m 2011-08-29 19:09:16 +0000 @@ -5316,7 +5316,7 @@ strcpy (old_title, t); } size_title = xmalloc (strlen (old_title) + 40); - sprintf (size_title, "%s — (%d x %d)", old_title, cols, rows); + esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows); [window setTitle: [NSString stringWithUTF8String: size_title]]; [window display]; xfree (size_title); === modified file 'src/print.c' --- src/print.c 2011-09-04 17:25:23 +0000 +++ src/print.c 2011-09-04 19:18:28 +0000 @@ -1016,12 +1016,15 @@ { width = 0; do - width = (width * 10) + (*cp++ - '0'); + { + width = (width * 10) + (*cp++ - '0'); + if (DBL_DIG < width) + goto lose; + } while (*cp >= '0' && *cp <= '9'); /* A precision of zero is valid only for %f. */ - if (width > DBL_DIG - || (width == 0 && *cp != 'f')) + if (width == 0 && *cp != 'f') goto lose; } @@ -1314,7 +1317,9 @@ static void print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag) { - char buf[40]; + char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT), + max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t), + 40))]; QUIT; @@ -1614,8 +1619,7 @@ PRINTCHAR ('('); { - EMACS_INT print_length; - int i; + printmax_t i, print_length; Lisp_Object halftail = obj; /* Negative values of print-length are invalid in CL. @@ -1623,7 +1627,7 @@ if (NATNUMP (Vprint_length)) print_length = XFASTINT (Vprint_length); else - print_length = 0; + print_length = TYPE_MAXIMUM (printmax_t); i = 0; while (CONSP (obj)) @@ -1634,7 +1638,7 @@ /* Simple but imcomplete way. */ if (i != 0 && EQ (obj, halftail)) { - sprintf (buf, " . #%d", i / 2); + sprintf (buf, " . #%"pMd, i / 2); strout (buf, -1, -1, printcharfun); goto end_of_list; } @@ -1654,15 +1658,16 @@ } } - if (i++) + if (i) PRINTCHAR (' '); - if (print_length && i > print_length) + if (print_length <= i) { strout ("...", 3, 3, printcharfun); goto end_of_list; } + i++; print_object (XCAR (obj), printcharfun, escapeflag); obj = XCDR (obj); @@ -1798,19 +1803,17 @@ PRINTCHAR (' '); strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun); PRINTCHAR (' '); - sprintf (buf, "%ld/%ld", (long) h->count, - (long) ASIZE (h->next)); + sprintf (buf, "%"pI"d/%"pI"d", h->count, ASIZE (h->next)); strout (buf, -1, -1, printcharfun); } - sprintf (buf, " 0x%lx", (unsigned long) h); + sprintf (buf, " %p", h); strout (buf, -1, -1, printcharfun); PRINTCHAR ('>'); #endif /* Implement a readable output, e.g.: #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ /* Always print the size. */ - sprintf (buf, "#s(hash-table size %ld", - (long) ASIZE (h->next)); + sprintf (buf, "#s(hash-table size %"pI"d", ASIZE (h->next)); strout (buf, -1, -1, printcharfun); if (!NILP (h->test)) @@ -2038,7 +2041,7 @@ if (MISCP (obj)) sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj)); else if (VECTORLIKEP (obj)) - sprintf (buf, "(PVEC 0x%08lx)", (unsigned long) ASIZE (obj)); + sprintf (buf, "(PVEC 0x%08"pI"x)", ASIZE (obj)); else sprintf (buf, "(0x%02x)", (int) XTYPE (obj)); strout (buf, -1, -1, printcharfun); === modified file 'src/process.c' --- src/process.c 2011-08-24 21:20:36 +0000 +++ src/process.c 2011-08-29 19:46:15 +0000 @@ -616,8 +616,8 @@ { register Lisp_Object val, tem, name1; register struct Lisp_Process *p; - char suffix[10]; - register int i; + char suffix[sizeof "<>" + INT_STRLEN_BOUND (printmax_t)]; + printmax_t i; p = allocate_process (); @@ -651,7 +651,7 @@ { tem = Fget_process (name1); if (NILP (tem)) break; - sprintf (suffix, "<%d>", i); + sprintf (suffix, "<%"pMd">", i); name1 = concat2 (name, build_string (suffix)); } name = name1; === modified file 'src/sysdep.c' --- src/sysdep.c 2011-07-29 01:16:54 +0000 +++ src/sysdep.c 2011-08-31 22:18:16 +0000 @@ -1811,6 +1811,45 @@ } #endif /* not WINDOWSNT */ #endif /* ! HAVE_STRERROR */ + +#ifndef HAVE_SNPRINTF +/* Approximate snprintf as best we can on ancient hosts that lack it. */ +int +snprintf (char *buf, size_t bufsize, char const *format, ...) +{ + ptrdiff_t size = min (bufsize, PTRDIFF_MAX); + ptrdiff_t nbytes = size - 1; + va_list ap; + + if (size) + { + va_start (ap, format); + nbytes = doprnt (buf, size, format, 0, ap); + va_end (ap); + } + + if (nbytes == size - 1) + { + /* Calculate the length of the string that would have been created + had the buffer been large enough. */ + char stackbuf[4000]; + char *b = stackbuf; + ptrdiff_t bsize = sizeof stackbuf; + va_start (ap, format); + nbytes = evxprintf (&b, &bsize, stackbuf, -1, format, ap); + va_end (ap); + if (b != stackbuf) + xfree (b); + } + + if (INT_MAX < nbytes) + { + errno = EOVERFLOW; + return -1; + } + return nbytes; +} +#endif int emacs_open (const char *path, int oflag, int mode) === modified file 'src/term.c' --- src/term.c 2011-08-30 17:32:44 +0000 +++ src/term.c 2011-08-30 21:16:49 +0000 @@ -1817,7 +1817,7 @@ { int face_id; int len; - char buf[9]; + char buf[sizeof "\\x" + max (6, (sizeof it->c * CHAR_BIT + 3) / 4)]; char const *str = " "; /* Get a face ID for the glyph by utilizing a cache (the same way as === modified file 'src/window.h' --- src/window.h 2011-07-02 10:36:48 +0000 +++ src/window.h 2011-08-29 15:43:34 +0000 @@ -847,11 +847,11 @@ /* Depth in recursive edits. */ -extern int command_loop_level; +extern EMACS_INT command_loop_level; /* Depth in minibuffer invocations. */ -extern int minibuf_level; +extern EMACS_INT minibuf_level; /* true if we should redraw the mode lines on the next redisplay. */ === modified file 'src/xfaces.c' --- src/xfaces.c 2011-08-19 14:28:36 +0000 +++ src/xfaces.c 2011-08-29 19:58:56 +0000 @@ -3549,6 +3549,8 @@ rdb != NULL)) { char line[512]; + char *buf = line; + ptrdiff_t bufsize = sizeof line; Lisp_Object lface = lface_from_face_name (f, Qmenu, 1); struct face *face = FACE_FROM_ID (f, MENU_FACE_ID); const char *myname = SSDATA (Vx_resource_name); @@ -3561,24 +3563,25 @@ if (STRINGP (LFACE_FOREGROUND (lface))) { - sprintf (line, "%s.%s*foreground: %s", - myname, popup_path, - SDATA (LFACE_FOREGROUND (lface))); + exprintf (&buf, &bufsize, line, -1, "%s.%s*foreground: %s", + myname, popup_path, + SDATA (LFACE_FOREGROUND (lface))); XrmPutLineResource (&rdb, line); - sprintf (line, "%s.pane.menubar*foreground: %s", - myname, SDATA (LFACE_FOREGROUND (lface))); + exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*foreground: %s", + myname, SDATA (LFACE_FOREGROUND (lface))); XrmPutLineResource (&rdb, line); changed_p = 1; } if (STRINGP (LFACE_BACKGROUND (lface))) { - sprintf (line, "%s.%s*background: %s", - myname, popup_path, - SDATA (LFACE_BACKGROUND (lface))); + exprintf (&buf, &bufsize, line, -1, "%s.%s*background: %s", + myname, popup_path, + SDATA (LFACE_BACKGROUND (lface))); XrmPutLineResource (&rdb, line); - sprintf (line, "%s.pane.menubar*background: %s", - myname, SDATA (LFACE_BACKGROUND (lface))); + + exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*background: %s", + myname, SDATA (LFACE_BACKGROUND (lface))); XrmPutLineResource (&rdb, line); changed_p = 1; } @@ -3616,11 +3619,12 @@ #else char *fontsetname = SSDATA (xlfd); #endif - sprintf (line, "%s.pane.menubar*font%s: %s", - myname, suffix, fontsetname); + exprintf (&buf, &bufsize, line, -1, "%s.pane.menubar*font%s: %s", + myname, suffix, fontsetname); XrmPutLineResource (&rdb, line); - sprintf (line, "%s.%s*font%s: %s", - myname, popup_path, suffix, fontsetname); + + exprintf (&buf, &bufsize, line, -1, "%s.%s*font%s: %s", + myname, popup_path, suffix, fontsetname); XrmPutLineResource (&rdb, line); changed_p = 1; if (fontsetname != SSDATA (xlfd)) @@ -3630,6 +3634,9 @@ if (changed_p && f->output_data.x->menubar_widget) free_frame_menubar (f); + + if (buf != line) + xfree (buf); } } === modified file 'src/xfns.c' --- src/xfns.c 2011-08-05 02:15:35 +0000 +++ src/xfns.c 2011-08-29 19:59:51 +0000 @@ -2440,7 +2440,7 @@ /* Do some needed geometry management. */ { ptrdiff_t len; - char *tem, shell_position[32]; + char *tem, shell_position[sizeof "=x++" + 4 * INT_STRLEN_BOUND (int)]; Arg gal[10]; int gac = 0; int extra_borders = 0; === modified file 'src/xterm.c' --- src/xterm.c 2011-08-05 02:19:34 +0000 +++ src/xterm.c 2011-09-01 14:44:49 +0000 @@ -7900,7 +7900,8 @@ { char buf[256]; - sprintf (buf, "Connection lost to X server `%s'", DisplayString (display)); + snprintf (buf, sizeof buf, "Connection lost to X server `%s'", + DisplayString (display)); x_connection_closed (display, buf); return 0; } === modified file 'src/xterm.h' --- src/xterm.h 2011-07-07 02:24:56 +0000 +++ src/xterm.h 2011-08-29 20:04:46 +0000 @@ -955,7 +955,8 @@ extern int x_text_icon (struct frame *, const char *); extern int x_bitmap_icon (struct frame *, Lisp_Object); extern void x_catch_errors (Display *); -extern void x_check_errors (Display *, const char *); +extern void x_check_errors (Display *, const char *) + ATTRIBUTE_FORMAT_PRINTF (2, 0); extern int x_had_errors_p (Display *); extern int x_catching_errors (void); extern void x_uncatch_errors (void); ------------------------------------------------------------ revno: 105654 [merge] committer: Paul Eggert branch nick: trunk timestamp: Sun 2011-09-04 12:14:54 -0700 message: Integer overflow fixes for scrolling, etc. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-09-03 22:20:00 +0000 +++ src/ChangeLog 2011-09-04 19:14:54 +0000 @@ -1,3 +1,39 @@ +2011-09-04 Paul Eggert + + Integer overflow fixes for scrolling, etc. + Without this fix, Emacs silently mishandles large integers sometimes. + For example, "C-u 4294967297 M-x recenter" was be treated as if + it were "C-u 1 M-x recenter" on a typical 64-bit host. + + * xdisp.c: Integer overflow fix. + (try_window_id): Check Emacs fixnum range before converting to 'int'. + + * window.c: Integer overflow fixes. + (window_scroll_line_based, Frecenter): + Check that an Emacs fixnum is in range before assigning it to 'int'. + (Frecenter, Fmove_to_window_line): Use EMACS_INT, not int, for + values converted from Emacs fixnums. + (Frecenter): Don't wrap around a line count if it is out of 'int' + range; instead, treat it as an extreme value. + (Fset_window_configuration, compare_window_configurations): + Use ptrdiff_t, not int, for index that might exceed 2 GiB. + + * search.c: Integer overflow fixes + (Freplace_match): Use ptrdiff_t, not int, for indexes that can + exceed INT_MAX. Check that EMACS_INT value is in range before + assigning it to the (possibly-narrower) index. + (match_limit): Don't assume that a fixnum can fit in 'int'. + + * print.c: Integer overflow fix. + (print_object): Use ptrdiff_t, not int, for index that can + exceed INT_MAX. + + * indent.c: Integer overflow fixes. + (position_indentation): Now takes ptrdiff_t, not int. + (Fvertical_motion): Don't wrap around LINES values that don't fit + in 'int'. Instead, treat them as extreme values. This is good + enough for windows, which can't have more than INT_MAX lines anyway. + 2011-09-03 Lars Magne Ingebrigtsen * Require libxml/parser.h to avoid compilation warning. === modified file 'src/indent.c' --- src/indent.c 2011-08-05 23:35:10 +0000 +++ src/indent.c 2011-09-04 17:24:12 +0000 @@ -56,7 +56,7 @@ static int last_known_column_modified; static EMACS_INT current_column_1 (void); -static EMACS_INT position_indentation (int); +static EMACS_INT position_indentation (ptrdiff_t); /* Cache of beginning of line found by the last call of current_column. */ @@ -855,7 +855,7 @@ } static EMACS_INT -position_indentation (register int pos_byte) +position_indentation (ptrdiff_t pos_byte) { register EMACS_INT column = 0; int tab_width = SANE_TAB_WIDTH (current_buffer); @@ -2063,7 +2063,7 @@ /* Do this even if LINES is 0, so that we move back to the beginning of the current line as we ought. */ if (XINT (lines) == 0 || IT_CHARPOS (it) > 0) - move_it_by_lines (&it, XINT (lines)); + move_it_by_lines (&it, max (INT_MIN, XINT (lines))); } else { @@ -2083,7 +2083,7 @@ && it.c == '\n')) move_it_by_lines (&it, -1); it.vpos = 0; - move_it_by_lines (&it, XINT (lines)); + move_it_by_lines (&it, min (INT_MAX, XINT (lines))); } else { @@ -2099,12 +2099,12 @@ move_it_by_lines (&it, 1); } if (XINT (lines) > 1) - move_it_by_lines (&it, XINT (lines) - 1); + move_it_by_lines (&it, min (INT_MAX, XINT (lines) - 1)); } else { it.vpos = 0; - move_it_by_lines (&it, XINT (lines)); + move_it_by_lines (&it, min (INT_MAX, XINT (lines))); } } } === modified file 'src/print.c' --- src/print.c 2011-07-28 20:23:19 +0000 +++ src/print.c 2011-09-04 17:25:23 +0000 @@ -1697,7 +1697,7 @@ } else if (BOOL_VECTOR_P (obj)) { - register int i; + ptrdiff_t i; register unsigned char c; struct gcpro gcpro1; EMACS_INT size_in_chars === modified file 'src/search.c' --- src/search.c 2011-08-05 02:15:35 +0000 +++ src/search.c 2011-09-04 17:27:38 +0000 @@ -2404,7 +2404,7 @@ int some_uppercase; int some_nonuppercase_initial; register int c, prevc; - int sub; + ptrdiff_t sub; EMACS_INT opoint, newpoint; CHECK_STRING (newtext); @@ -2423,9 +2423,9 @@ else { CHECK_NUMBER (subexp); + if (! (0 <= XINT (subexp) && XINT (subexp) < search_regs.num_regs)) + args_out_of_range (subexp, make_number (search_regs.num_regs)); sub = XINT (subexp); - if (sub < 0 || sub >= search_regs.num_regs) - args_out_of_range (subexp, make_number (search_regs.num_regs)); } if (NILP (string)) @@ -2662,7 +2662,7 @@ unsigned char str[MAX_MULTIBYTE_LENGTH]; const unsigned char *add_stuff = NULL; ptrdiff_t add_len = 0; - int idx = -1; + ptrdiff_t idx = -1; if (str_multibyte) { @@ -2813,7 +2813,7 @@ static Lisp_Object match_limit (Lisp_Object num, int beginningp) { - register int n; + EMACS_INT n; CHECK_NUMBER (num); n = XINT (num); === modified file 'src/window.c' --- src/window.c 2011-08-05 23:35:10 +0000 +++ src/window.c 2011-09-04 18:46:51 +0000 @@ -4662,14 +4662,9 @@ if (pos < ZV) { - int this_scroll_margin = scroll_margin; - /* Don't use a scroll margin that is negative or too large. */ - if (this_scroll_margin < 0) - this_scroll_margin = 0; - - if (XINT (w->total_lines) < 4 * scroll_margin) - this_scroll_margin = XINT (w->total_lines) / 4; + int this_scroll_margin = + max (0, min (scroll_margin, XINT (w->total_lines) / 4)); set_marker_restricted_both (w->start, w->buffer, pos, pos_byte); w->start_at_line_beg = bolp; @@ -5057,7 +5052,7 @@ struct buffer *obuf = current_buffer; int center_p = 0; EMACS_INT charpos, bytepos; - int iarg IF_LINT (= 0); + EMACS_INT iarg IF_LINT (= 0); int this_scroll_margin; /* If redisplay is suppressed due to an error, try again. */ @@ -5096,9 +5091,8 @@ /* Do this after making BUF current in case scroll_margin is buffer-local. */ - this_scroll_margin = max (0, scroll_margin); - this_scroll_margin = min (this_scroll_margin, - XFASTINT (w->total_lines) / 4); + this_scroll_margin = + max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4)); /* Handle centering on a graphical frame specially. Such frames can have variable-height lines and centering point on the basis of @@ -5122,7 +5116,7 @@ { struct it it; struct text_pos pt; - int nlines = -iarg; + int nlines = min (INT_MAX, -iarg); int extra_line_spacing; int h = window_box_height (w); void *itdata = bidi_shelve_cache (); @@ -5288,15 +5282,14 @@ lines = displayed_window_lines (w); #if 0 - this_scroll_margin = max (0, scroll_margin); - this_scroll_margin = min (this_scroll_margin, lines / 4); + this_scroll_margin = max (0, min (scroll_margin, lines / 4)); #endif if (NILP (arg)) XSETFASTINT (arg, lines / 2); else { - int iarg = XINT (Fprefix_numeric_value (arg)); + EMACS_INT iarg = XINT (Fprefix_numeric_value (arg)); if (iarg < 0) iarg = iarg + lines; @@ -5468,7 +5461,8 @@ struct window *root_window; struct window **leaf_windows; int n_leaf_windows; - int k, i, n; + ptrdiff_t k; + int i, n; /* If the frame has been resized since this window configuration was made, we change the frame to the size specified in the @@ -6344,7 +6338,7 @@ { register struct save_window_data *d1, *d2; struct Lisp_Vector *sws1, *sws2; - int i; + ptrdiff_t i; CHECK_WINDOW_CONFIGURATION (configuration1); CHECK_WINDOW_CONFIGURATION (configuration2); === modified file 'src/xdisp.c' --- src/xdisp.c 2011-08-30 17:32:44 +0000 +++ src/xdisp.c 2011-09-04 18:48:35 +0000 @@ -16919,8 +16919,8 @@ { int this_scroll_margin, cursor_height; - this_scroll_margin = max (0, scroll_margin); - this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4); + this_scroll_margin = + max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)); this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height; ------------------------------------------------------------ revno: 105653 committer: Michael Albinus branch nick: trunk timestamp: Sun 2011-09-04 20:14:34 +0200 message: * net/tramp.el (top): Require 'shell. Use `tramp-unload-hook' but `tramp-cache-unload-hook' where appropriate. (tramp-methods): Rename `tramp-remote-sh' to `tramp-remote-shell'. Add `tramp-remote-shell-args'. (tramp-handle-shell-command): New defun, moved from tramp-sh.el. * net/tramp-sh.el (top): Don't require 'shell. (tramp-methods): Add `tramp-remote-shell' and `tramp-remote-shell-args' entries. (tramp-sh-file-name-handler-alist): Use `tramp-handle-shell-command'. (tramp-sh-handle-shell-command): Remove. (tramp-find-shell, tramp-open-connection-setup-interactive-shell): Use `tramp-remote-shell'. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-09-03 20:24:12 +0000 +++ lisp/ChangeLog 2011-09-04 18:14:34 +0000 @@ -1,3 +1,19 @@ +2011-09-04 Michael Albinus + + * net/tramp.el (top): Require 'shell. Use `tramp-unload-hook' but + `tramp-cache-unload-hook' where appropriate. + (tramp-methods): Rename `tramp-remote-sh' to + `tramp-remote-shell'. Add `tramp-remote-shell-args'. + (tramp-handle-shell-command): New defun, moved from tramp-sh.el. + + * net/tramp-sh.el (top): Don't require 'shell. + (tramp-methods): Add `tramp-remote-shell' and + `tramp-remote-shell-args' entries. + (tramp-sh-file-name-handler-alist): Use `tramp-handle-shell-command'. + (tramp-sh-handle-shell-command): Remove. + (tramp-find-shell, tramp-open-connection-setup-interactive-shell): + Use `tramp-remote-shell'. + 2011-09-03 Chong Yidong * mail/sendmail.el (sendmail-query-once-function): Deleted. === modified file 'lisp/net/tramp-sh.el' --- lisp/net/tramp-sh.el 2011-08-03 19:31:18 +0000 +++ lisp/net/tramp-sh.el 2011-09-04 18:14:34 +0000 @@ -28,7 +28,6 @@ (eval-when-compile (require 'cl)) ; ignore-errors (require 'tramp) -(require 'shell) ;; Pacify byte-compiler. The function is needed on XEmacs only. I'm ;; not sure at all that this is the right way to do it, but let's hope @@ -91,7 +90,8 @@ '("rcp" (tramp-login-program "rsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "rcp") (tramp-copy-args (("-p" "%k") ("-r"))) (tramp-copy-keep-date t) @@ -101,7 +101,8 @@ '("remcp" (tramp-login-program "remsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "rcp") (tramp-copy-args (("-p" "%k"))) (tramp-copy-keep-date t))) @@ -111,7 +112,8 @@ (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r"))) (tramp-copy-keep-date t) @@ -127,7 +129,8 @@ (tramp-login-args (("-l" "%u") ("-p" "%p") ("-1") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-1") ("-P" "%p") ("-p" "%k") ("-q") ("-r"))) (tramp-copy-keep-date t) @@ -143,7 +146,8 @@ (tramp-login-args (("-l" "%u") ("-p" "%p") ("-2") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-2") ("-P" "%p") ("-p" "%k") ("-q") ("-r"))) (tramp-copy-keep-date t) @@ -161,7 +165,8 @@ ("-o" "ControlMaster=yes") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r") ("-o" "ControlPath=%t.%%r@%%h:%%p") @@ -180,7 +185,8 @@ ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r"))) (tramp-copy-keep-date t) @@ -195,7 +201,8 @@ (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "sftp"))) ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -203,7 +210,8 @@ (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "rsync") (tramp-copy-args (("-e" "ssh") ("-t" "%k") ("-r"))) (tramp-copy-keep-date t) @@ -218,7 +226,8 @@ ("-o" "ControlMaster=yes") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "rsync") (tramp-copy-args (("-t" "%k") ("-r"))) (tramp-copy-env (("RSYNC_RSH") @@ -234,20 +243,23 @@ '("rsh" (tramp-login-program "rsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-sh "/bin/sh"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("remsh" (tramp-login-program "remsh") (tramp-login-args (("%h") ("-l" "%u"))) - (tramp-remote-sh "/bin/sh"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("ssh" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") ("-o" "StrictHostKeyChecking=no"))) @@ -259,7 +271,8 @@ (tramp-login-args (("-l" "%u") ("-p" "%p") ("-1") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") ("-o" "StrictHostKeyChecking=no"))) @@ -271,7 +284,8 @@ (tramp-login-args (("-l" "%u") ("-p" "%p") ("-2") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") ("-o" "StrictHostKeyChecking=no"))) @@ -284,7 +298,8 @@ ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh"))) (tramp-async-args (("-q"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") ("-o" "StrictHostKeyChecking=no"))) @@ -294,38 +309,44 @@ '("telnet" (tramp-login-program "telnet") (tramp-login-args (("%h") ("%p"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-default-port 23))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("su" (tramp-login-program "su") (tramp-login-args (("-") ("%u"))) - (tramp-remote-sh "/bin/sh"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("sudo" (tramp-login-program "sudo") (tramp-login-args (("-u" "%u") ("-s") ("-H") ("-p" "Password:"))) - (tramp-remote-sh "/bin/sh"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("ksu" (tramp-login-program "ksu") (tramp-login-args (("%u") ("-q"))) - (tramp-remote-sh "/bin/sh"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("krlogin" (tramp-login-program "krlogin") (tramp-login-args (("%h") ("-l" "%u") ("-x"))) - (tramp-remote-sh "/bin/sh"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("plink" (tramp-login-program "plink") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-password-end-of-line "xy") ;see docstring for "xy" (tramp-default-port 22))) ;;;###tramp-autoload @@ -333,7 +354,8 @@ '("plink1" (tramp-login-program "plink") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-1" "-ssh") ("%h"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-password-end-of-line "xy") ;see docstring for "xy" (tramp-default-port 22))) ;;;###tramp-autoload @@ -348,13 +370,15 @@ tramp-terminal-type tramp-initial-end-of-output)) ("/bin/sh"))) - (tramp-remote-sh "/bin/sh"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods '("pscp" (tramp-login-program "plink") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") (tramp-copy-args (("-P" "%p") ("-scp") ("-p" "%k") ("-q") ("-r"))) @@ -367,7 +391,8 @@ '("psftp" (tramp-login-program "plink") (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h"))) - (tramp-remote-sh "/bin/sh") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") (tramp-copy-args (("-P" "%p") ("-sftp") ("-p" "%k") ("-q") ("-r"))) @@ -379,7 +404,8 @@ '("fcp" (tramp-login-program "fsh") (tramp-login-args (("%h") ("-l" "%u") ("sh" "-i"))) - (tramp-remote-sh "/bin/sh -i") + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-i") ("-c")) (tramp-copy-program "fcp") (tramp-copy-args (("-p" "%k"))) (tramp-copy-keep-date t))) @@ -942,7 +968,7 @@ (executable-find . tramp-sh-handle-executable-find) (start-file-process . tramp-sh-handle-start-file-process) (process-file . tramp-sh-handle-process-file) - (shell-command . tramp-sh-handle-shell-command) + (shell-command . tramp-handle-shell-command) (insert-directory . tramp-sh-handle-insert-directory) (expand-file-name . tramp-sh-handle-expand-file-name) (substitute-in-file-name . tramp-handle-substitute-in-file-name) @@ -2853,7 +2879,7 @@ ;; `process-file-side-effects' has been introduced with GNU ;; Emacs 23.2. If set to `nil', no remote file will be changed ;; by `program'. If it doesn't exist, we assume its default - ;; value 't'. + ;; value `t'. (unless (and (boundp 'process-file-side-effects) (not (symbol-value 'process-file-side-effects))) (tramp-flush-directory-property v "")) @@ -2873,87 +2899,6 @@ (apply 'call-process program tmpfile buffer display args) (delete-file tmpfile)))) -(defun tramp-sh-handle-shell-command - (command &optional output-buffer error-buffer) - "Like `shell-command' for Tramp files." - (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) - ;; We cannot use `shell-file-name' and `shell-command-switch', - ;; they are variables of the local host. - (args (list - (tramp-get-method-parameter - (tramp-file-name-method - (tramp-dissect-file-name default-directory)) - 'tramp-remote-sh) - "-c" (substring command 0 asynchronous))) - current-buffer-p - (output-buffer - (cond - ((bufferp output-buffer) output-buffer) - ((stringp output-buffer) (get-buffer-create output-buffer)) - (output-buffer - (setq current-buffer-p t) - (current-buffer)) - (t (get-buffer-create - (if asynchronous - "*Async Shell Command*" - "*Shell Command Output*"))))) - (error-buffer - (cond - ((bufferp error-buffer) error-buffer) - ((stringp error-buffer) (get-buffer-create error-buffer)))) - (buffer - (if (and (not asynchronous) error-buffer) - (with-parsed-tramp-file-name default-directory nil - (list output-buffer (tramp-make-tramp-temp-file v))) - output-buffer)) - (p (get-buffer-process output-buffer))) - - ;; Check whether there is another process running. Tramp does not - ;; support 2 (asynchronous) processes in parallel. - (when p - (if (yes-or-no-p "A command is running. Kill it? ") - (ignore-errors (kill-process p)) - (error "Shell command in progress"))) - - (if current-buffer-p - (progn - (barf-if-buffer-read-only) - (push-mark nil t)) - (with-current-buffer output-buffer - (setq buffer-read-only nil) - (erase-buffer))) - - (if (and (not current-buffer-p) (integerp asynchronous)) - (prog1 - ;; Run the process. - (apply 'start-file-process "*Async Shell*" buffer args) - ;; Display output. - (pop-to-buffer output-buffer) - (setq mode-line-process '(":%s")) - (shell-mode)) - - (prog1 - ;; Run the process. - (apply 'process-file (car args) nil buffer nil (cdr args)) - ;; Insert error messages if they were separated. - (when (listp buffer) - (with-current-buffer error-buffer - (insert-file-contents (cadr buffer))) - (delete-file (cadr buffer))) - (if current-buffer-p - ;; This is like exchange-point-and-mark, but doesn't - ;; activate the mark. It is cleaner to avoid activation, - ;; even though the command loop would deactivate the mark - ;; because we inserted text. - (goto-char (prog1 (mark t) - (set-marker (mark-marker) (point) - (current-buffer)))) - ;; There's some output, display it. - (when (with-current-buffer output-buffer (> (point-max) (point-min))) - (if (functionp 'display-message-or-buffer) - (tramp-compat-funcall 'display-message-or-buffer output-buffer) - (pop-to-buffer output-buffer)))))))) - (defun tramp-sh-handle-file-local-copy (filename) "Like `file-local-copy' for Tramp files." (with-parsed-tramp-file-name filename nil @@ -3680,7 +3625,7 @@ (tramp-set-connection-property vec "remote-shell" (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-remote-sh))))))))) + (tramp-file-name-method vec) 'tramp-remote-shell))))))))) ;; Utility functions. @@ -3716,7 +3661,8 @@ ;; discarded as well. (tramp-open-shell vec - (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-remote-sh)) + (tramp-get-method-parameter + (tramp-file-name-method vec) 'tramp-remote-shell)) ;; Disable echo. (tramp-message vec 5 "Setting up remote shell environment") === modified file 'lisp/net/tramp.el' --- lisp/net/tramp.el 2011-08-31 08:18:20 +0000 +++ lisp/net/tramp.el 2011-09-04 18:14:34 +0000 @@ -58,6 +58,7 @@ ;;; Code: (require 'tramp-compat) +(require 'shell) ;;; User Customizable Internal Variables: @@ -190,13 +191,16 @@ This is a list of entries of the form (NAME PARAM1 PARAM2 ...). Each NAME stands for a remote access method. Each PARAM is a pair of the form (KEY VALUE). The following KEYs are defined: - * `tramp-remote-sh' + * `tramp-remote-shell' This specifies the Bourne shell to use on the remote host. This MUST be a Bourne-like shell. It is normally not necessary to set this to any value other than \"/bin/sh\": Tramp wants to use a shell which groks tilde expansion, but it can search for it. Also note that \"/bin/sh\" exists on all Unixen, this might not be true for the value that you decide to use. You Have Been Warned. + * `tramp-remote-shell-args' + For implementation of `shell-command', this specifies the + argument to let `tramp-remote-shell' run a command. * `tramp-login-program' This specifies the name of the program to use for logging in to the remote host. This may be the name of rsh or a workalike program, @@ -2959,6 +2963,92 @@ (delete-file local-copy))))) t))) +(defun tramp-handle-shell-command + (command &optional output-buffer error-buffer) + "Like `shell-command' for Tramp files." + (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) + ;; We cannot use `shell-file-name' and `shell-command-switch', + ;; they are variables of the local host. + (args (append + (cons + (tramp-get-method-parameter + (tramp-file-name-method + (tramp-dissect-file-name default-directory)) + 'tramp-remote-shell) + (tramp-get-method-parameter + (tramp-file-name-method + (tramp-dissect-file-name default-directory)) + 'tramp-remote-shell-args)) + (list (substring command 0 asynchronous)))) + current-buffer-p + (output-buffer + (cond + ((bufferp output-buffer) output-buffer) + ((stringp output-buffer) (get-buffer-create output-buffer)) + (output-buffer + (setq current-buffer-p t) + (current-buffer)) + (t (get-buffer-create + (if asynchronous + "*Async Shell Command*" + "*Shell Command Output*"))))) + (error-buffer + (cond + ((bufferp error-buffer) error-buffer) + ((stringp error-buffer) (get-buffer-create error-buffer)))) + (buffer + (if (and (not asynchronous) error-buffer) + (with-parsed-tramp-file-name default-directory nil + (list output-buffer (tramp-make-tramp-temp-file v))) + output-buffer)) + (p (get-buffer-process output-buffer))) + + ;; Check whether there is another process running. Tramp does not + ;; support 2 (asynchronous) processes in parallel. + (when p + (if (yes-or-no-p "A command is running. Kill it? ") + (ignore-errors (kill-process p)) + (error "Shell command in progress"))) + + (if current-buffer-p + (progn + (barf-if-buffer-read-only) + (push-mark nil t)) + (with-current-buffer output-buffer + (setq buffer-read-only nil) + (erase-buffer))) + + (if (and (not current-buffer-p) (integerp asynchronous)) + (prog1 + ;; Run the process. + (apply 'start-file-process "*Async Shell*" buffer args) + ;; Display output. + (pop-to-buffer output-buffer) + (setq mode-line-process '(":%s")) + (shell-mode)) + + (prog1 + ;; Run the process. + (apply 'process-file (car args) nil buffer nil (cdr args)) + ;; Insert error messages if they were separated. + (when (listp buffer) + (with-current-buffer error-buffer + (insert-file-contents (cadr buffer))) + (delete-file (cadr buffer))) + (if current-buffer-p + ;; This is like exchange-point-and-mark, but doesn't + ;; activate the mark. It is cleaner to avoid activation, + ;; even though the command loop would deactivate the mark + ;; because we inserted text. + (goto-char (prog1 (mark t) + (set-marker (mark-marker) (point) + (current-buffer)))) + ;; There's some output, display it. + (when (with-current-buffer output-buffer (> (point-max) (point-min))) + (if (functionp 'display-message-or-buffer) + (tramp-compat-funcall 'display-message-or-buffer output-buffer) + (pop-to-buffer output-buffer)))))))) + (defun tramp-handle-substitute-in-file-name (filename) "Like `substitute-in-file-name' for Tramp files. \"//\" and \"/~\" substitute only in the local filename part. @@ -3477,7 +3567,7 @@ (ignore-errors (delete-file tramp-temp-buffer-file-name)))) (add-hook 'kill-buffer-hook 'tramp-delete-temp-file-function) -(add-hook 'tramp-cache-unload-hook +(add-hook 'tramp-unload-hook (lambda () (remove-hook 'kill-buffer-hook 'tramp-delete-temp-file-function))) ------------------------------------------------------------ revno: 105652 fixes bug(s): http://debbugs.gnu.org/9433 committer: Eli Zaretskii branch nick: trunk timestamp: Sun 2011-09-04 19:53:44 +0300 message: Fix bug #9433 with indexing of C-x 8 RET. doc/emacs/basic.texi (Inserting Text): Add index entries. diff: === modified file 'doc/emacs/ChangeLog' --- doc/emacs/ChangeLog 2011-08-29 22:02:21 +0000 +++ doc/emacs/ChangeLog 2011-09-04 16:53:44 +0000 @@ -1,3 +1,7 @@ +2011-09-04 Eli Zaretskii + + * basic.texi (Inserting Text): Add index entries. (Bug#9433) + 2011-08-29 Chong Yidong * modes.texi (Choosing Modes): auto-mode-case-fold is now t. === modified file 'doc/emacs/basic.texi' --- doc/emacs/basic.texi 2011-01-25 04:08:28 +0000 +++ doc/emacs/basic.texi 2011-09-04 16:53:44 +0000 @@ -101,7 +101,9 @@ @findex ucs-insert @kindex C-x 8 RET -@cindex Unicode +@cindex Unicode characters, inserting +@cindex insert Unicode character +@cindex characters, inserting by name or code-point Instead of @kbd{C-q}, you can use @kbd{C-x 8 @key{RET}} (@code{ucs-insert}) to insert a character based on its Unicode name or code-point. This command prompts for a character to insert, using ------------------------------------------------------------ revno: 105651 author: Lars Magne Ingebrigtsen committer: Katsumi Yamaoka branch nick: trunk timestamp: Sat 2011-09-03 22:51:26 +0000 message: nnimap.el (nnimap-open-connection-1): Use the correct port number in the error message. diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2011-09-02 17:57:45 +0000 +++ lisp/gnus/ChangeLog 2011-09-03 22:51:26 +0000 @@ -1,3 +1,8 @@ +2011-09-03 Lars Magne Ingebrigtsen + + * nnimap.el (nnimap-open-connection-1): Use the correct port number in + the error message. + 2011-09-02 Eli Zaretskii * message.el (message-setup-1): Return t (Bug#9392). === modified file 'lisp/gnus/nnimap.el' --- lisp/gnus/nnimap.el 2011-08-20 00:20:39 +0000 +++ lisp/gnus/nnimap.el 2011-09-03 22:51:26 +0000 @@ -350,7 +350,6 @@ (with-current-buffer (nnimap-make-process-buffer buffer) (let* ((coding-system-for-read 'binary) (coding-system-for-write 'binary) - (port nil) (ports (cond ((memq nnimap-stream '(network plain starttls)) @@ -395,7 +394,7 @@ (if (not stream) (progn (nnheader-report 'nnimap "Unable to contact %s:%s via %s" - nnimap-address port nnimap-stream) + nnimap-address (car ports) nnimap-stream) 'no-connect) (gnus-set-process-query-on-exit-flag stream nil) (if (not (gnus-string-match-p "[*.] \\(OK\\|PREAUTH\\)" greeting)) ------------------------------------------------------------ Use --include-merges or -n0 to see merged revisions.