Now on revision 114515. ------------------------------------------------------------ revno: 114515 committer: Paul Eggert branch nick: trunk timestamp: Thu 2013-10-03 23:51:50 -0700 message: * bytecode.c (exec_byte_code): Use some more volatile variables to work around local variables getting clobbered by longjmp. Port to pre-C99, which doesn't allow decls after stmts. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-03 16:16:31 +0000 +++ src/ChangeLog 2013-10-04 06:51:50 +0000 @@ -1,3 +1,9 @@ +2013-10-04 Paul Eggert + + * bytecode.c (exec_byte_code): Use some more volatile variables + to work around local variables getting clobbered by longjmp. + Port to pre-C99, which doesn't allow decls after stmts. + 2013-10-03 Paul Eggert * lisp.h (eassert): Assume that COND is true when optimizing. === modified file 'src/bytecode.c' --- src/bytecode.c 2013-10-03 04:58:56 +0000 +++ src/bytecode.c 2013-10-04 06:51:50 +0000 @@ -332,7 +332,7 @@ /* A list of currently active byte-code execution value stacks. Fbyte_code adds an entry to the head of this list before it starts - processing byte-code, and it removed the entry again when it is + processing byte-code, and it removes the entry again when it is done. Signaling an error truncates the list analogous to gcprolist. */ @@ -501,19 +501,22 @@ Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args) { ptrdiff_t count = SPECPDL_INDEX (); + ptrdiff_t volatile count_volatile; #ifdef BYTE_CODE_METER - int this_op = 0; + int volatile this_op = 0; int prev_op; #endif int op; /* Lisp_Object v1, v2; */ Lisp_Object *vectorp; + Lisp_Object *volatile vectorp_volatile; #ifdef BYTE_CODE_SAFE - ptrdiff_t const_length; - Lisp_Object *stacke; - ptrdiff_t bytestr_length; + ptrdiff_t volatile const_length; + Lisp_Object *volatile stacke; + ptrdiff_t volatile bytestr_length; #endif struct byte_stack stack; + struct byte_stack volatile stack_volatile; Lisp_Object *top; Lisp_Object result; enum handlertype type; @@ -1119,16 +1122,25 @@ PUSH_HANDLER (c, tag, type); c->bytecode_dest = dest; c->bytecode_top = top; + count_volatile = count; + stack_volatile = stack; + vectorp_volatile = vectorp; + if (sys_setjmp (c->jmp)) { struct handler *c = handlerlist; + int dest; top = c->bytecode_top; - int dest = c->bytecode_dest; + dest = c->bytecode_dest; handlerlist = c->next; PUSH (c->val); CHECK_RANGE (dest); + stack = stack_volatile; stack.pc = stack.byte_string_start + dest; } + + count = count_volatile; + vectorp = vectorp_volatile; NEXT; } ------------------------------------------------------------ revno: 114514 author: Jorgen Schaefer committer: Stefan Monnier branch nick: trunk timestamp: Thu 2013-10-03 22:12:16 -0400 message: * lisp/minibuffer.el (completion--replace): Be careful that `end' might be a marker. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-03 07:11:27 +0000 +++ lisp/ChangeLog 2013-10-04 02:12:16 +0000 @@ -1,3 +1,8 @@ +2013-10-04 Jorgen Schaefer + + * minibuffer.el (completion--replace): Be careful that `end' might be + a marker. + 2013-10-03 Daiki Ueno Add support for package signature checking. === modified file 'lisp/minibuffer.el' --- lisp/minibuffer.el 2013-09-26 00:46:29 +0000 +++ lisp/minibuffer.el 2013-10-04 02:12:16 +0000 @@ -873,8 +873,9 @@ (setq end (- end suffix-len)) (setq newtext (substring newtext 0 (- suffix-len)))) (goto-char beg) - (insert-and-inherit newtext) - (delete-region (point) (+ (point) (- end beg))) + (let ((length (- end beg))) ;Read `end' before we insert the text. + (insert-and-inherit newtext) + (delete-region (point) (+ (point) length))) (forward-char suffix-len))) (defcustom completion-cycle-threshold nil ------------------------------------------------------------ revno: 114513 committer: Paul Eggert branch nick: trunk timestamp: Thu 2013-10-03 09:16:31 -0700 message: * lisp.h (eassert): Assume that COND is true when optimizing. In other words, take on the behavior of eassert_and_assume. This makes Emacs 0.2% smaller on my platform (Fedora 19, x86-64). (eassert_and_assume): Remove. All uses replaced by eassert. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-03 13:55:28 +0000 +++ src/ChangeLog 2013-10-03 16:16:31 +0000 @@ -1,5 +1,10 @@ 2013-10-03 Paul Eggert + * lisp.h (eassert): Assume that COND is true when optimizing. + In other words, take on the behavior of eassert_and_assume. + This makes Emacs 0.2% smaller on my platform (Fedora 19, x86-64). + (eassert_and_assume): Remove. All uses replaced by eassert. + * xdisp.c (Qglyphless_char): Now static. Adjust to merge from gnulib. === modified file 'src/alloc.c' --- src/alloc.c 2013-10-03 04:58:56 +0000 +++ src/alloc.c 2013-10-03 16:16:31 +0000 @@ -2023,7 +2023,7 @@ ptrdiff_t exact_needed_bytes; ptrdiff_t needed_bytes; - eassert_and_assume (nr_bits >= 0); + eassert (nr_bits >= 0); exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT; needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_SIZE_T) / CHAR_BIT; @@ -2060,8 +2060,8 @@ total_payload_bytes = bool_vector_payload_bytes (XFASTINT (length), &exact_payload_bytes); - eassert_and_assume (exact_payload_bytes <= total_payload_bytes); - eassert_and_assume (0 <= exact_payload_bytes); + eassert (exact_payload_bytes <= total_payload_bytes); + eassert (0 <= exact_payload_bytes); needed_elements = ROUNDUP ((size_t) ((bool_header_size - header_size) + total_payload_bytes), @@ -2816,7 +2816,7 @@ ptrdiff_t payload_bytes = bool_vector_payload_bytes (bv->size, NULL); - eassert_and_assume (payload_bytes >= 0); + eassert (payload_bytes >= 0); size = bool_header_size + ROUNDUP (payload_bytes, word_size); } else === modified file 'src/data.c' --- src/data.c 2013-09-24 14:53:49 +0000 +++ src/data.c 2013-10-03 16:16:31 +0000 @@ -2966,7 +2966,7 @@ static size_t bool_vector_spare_mask (ptrdiff_t nr_bits) { - eassert_and_assume (nr_bits > 0); + eassert (nr_bits > 0); return (((size_t) 1) << (nr_bits % BITS_PER_SIZE_T)) - 1; } @@ -3108,7 +3108,7 @@ nr_bits = min (nr_bits, XBOOL_VECTOR (dest)->size); } - eassert_and_assume (nr_bits >= 0); + eassert (nr_bits >= 0); nr_words = ROUNDUP (nr_bits, BITS_PER_SIZE_T) / BITS_PER_SIZE_T; adata = (size_t *) XBOOL_VECTOR (dest)->data; @@ -3275,7 +3275,7 @@ bdata = (size_t *) XBOOL_VECTOR (b)->data; adata = (size_t *) XBOOL_VECTOR (a)->data; - eassert_and_assume (nr_bits >= 0); + eassert (nr_bits >= 0); for (i = 0; i < nr_bits / BITS_PER_SIZE_T; i++) bdata[i] = ~adata[i]; @@ -3310,7 +3310,7 @@ match = NILP (b) ? (size_t) -1 : 0; adata = (size_t *) XBOOL_VECTOR (a)->data; - eassert_and_assume (nr_bits >= 0); + eassert (nr_bits >= 0); for (i = 0; i < nr_bits / BITS_PER_SIZE_T; ++i) count += popcount_size_t (adata[i] ^ match); === modified file 'src/lisp.h' --- src/lisp.h 2013-10-03 13:55:28 +0000 +++ src/lisp.h 2013-10-03 16:16:31 +0000 @@ -108,11 +108,12 @@ /* Extra internal type checking? */ -/* Define an Emacs version of 'assert (COND)', since some - system-defined 'assert's are flaky. COND should be free of side - effects; it may or may not be evaluated. */ +/* Define an Emacs version of 'assert (COND)'. COND should be free of + side effects; it may be evaluated zero or more times. If COND is false, + Emacs reliably crashes if ENABLE_CHECKING is defined and behavior + is undefined if not. The compiler may assume COND while optimizing. */ #ifndef ENABLE_CHECKING -# define eassert(X) ((void) (0 && (X))) /* Check that X compiles. */ +# define eassert(cond) assume (cond) #else /* ENABLE_CHECKING */ extern _Noreturn void die (const char *, const char *, int); @@ -129,16 +130,10 @@ # define eassert(cond) \ (suppress_checking || (cond) \ - ? (void) 0 \ + ? assume (cond) \ : die (# cond, __FILE__, __LINE__)) #endif /* ENABLE_CHECKING */ -/* When checking is enabled, identical to eassert. When checking is - * disabled, instruct the compiler (when the compiler has such - * capability) to assume that cond is true and optimize - * accordingly. */ -#define eassert_and_assume(cond) (eassert (cond), assume (cond)) - /* Use the configure flag --enable-check-lisp-object-type to make Lisp_Object use a struct type instead of the default int. The flag ------------------------------------------------------------ revno: 114512 committer: Xue Fuqiao branch nick: trunk timestamp: Thu 2013-10-03 23:32:10 +0800 message: Add an index for modify-syntax-entry. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-10-03 15:09:18 +0000 +++ doc/lispref/ChangeLog 2013-10-03 15:32:10 +0000 @@ -1,6 +1,7 @@ 2013-10-03 Xue Fuqiao - * syntax.texi (Syntax Flags): Add an index for comment style. + * syntax.texi (Syntax Flags): + (Syntax Table Functions): Add indexes. 2013-10-02 Xue Fuqiao === modified file 'doc/lispref/syntax.texi' --- doc/lispref/syntax.texi 2013-10-03 15:09:18 +0000 +++ doc/lispref/syntax.texi 2013-10-03 15:32:10 +0000 @@ -411,6 +411,7 @@ @end defun @deffn Command modify-syntax-entry char syntax-descriptor &optional table +@cindex syntax entry, setting This function sets the syntax entry for @var{char} according to @var{syntax-descriptor}. @var{char} must be a character, or a cons cell of the form @code{(@var{min} . @var{max})}; in the latter case, ------------------------------------------------------------ revno: 114511 committer: Xue Fuqiao branch nick: trunk timestamp: Thu 2013-10-03 23:09:18 +0800 message: * doc/lispref/syntax.texi (Syntax Flags): Add an index for comment style. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-10-02 15:14:06 +0000 +++ doc/lispref/ChangeLog 2013-10-03 15:09:18 +0000 @@ -1,3 +1,7 @@ +2013-10-03 Xue Fuqiao + + * syntax.texi (Syntax Flags): Add an index for comment style. + 2013-10-02 Xue Fuqiao * syntax.texi (Syntax Class Table): Add an index for syntax class table. === modified file 'doc/lispref/syntax.texi' --- doc/lispref/syntax.texi 2013-10-02 15:14:06 +0000 +++ doc/lispref/syntax.texi 2013-10-03 15:09:18 +0000 @@ -336,6 +336,7 @@ comment delimiter, @samp{n} on either character makes it nestable. +@cindex comment style Emacs supports several comment styles simultaneously in any one syntax table. A comment style is a set of flags @samp{b}, @samp{c}, and @samp{n}, so there can be up to 8 different comment styles. ------------------------------------------------------------ revno: 114510 committer: Paul Eggert branch nick: trunk timestamp: Thu 2013-10-03 06:55:28 -0700 message: * xdisp.c (Qglyphless_char): Now static. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-03 07:06:52 +0000 +++ src/ChangeLog 2013-10-03 13:55:28 +0000 @@ -1,5 +1,7 @@ 2013-10-03 Paul Eggert + * xdisp.c (Qglyphless_char): Now static. + Adjust to merge from gnulib. * conf_post.h (__has_builtin, assume): Remove; gnulib now does these. * lisp.h: Include , for 'assume'. === modified file 'src/lisp.h' --- src/lisp.h 2013-10-03 07:06:52 +0000 +++ src/lisp.h 2013-10-03 13:55:28 +0000 @@ -3389,7 +3389,6 @@ extern Lisp_Object Qspace, Qcenter, QCalign_to; extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow; extern Lisp_Object Qleft_margin, Qright_margin; -extern Lisp_Object Qglyphless_char; extern Lisp_Object QCdata, QCfile; extern Lisp_Object QCmap; extern Lisp_Object Qrisky_local_variable; === modified file 'src/xdisp.c' --- src/xdisp.c 2013-09-29 16:27:09 +0000 +++ src/xdisp.c 2013-10-03 13:55:28 +0000 @@ -751,7 +751,7 @@ #endif /* HAVE_WINDOW_SYSTEM */ /* Name of the face used to display glyphless characters. */ -Lisp_Object Qglyphless_char; +static Lisp_Object Qglyphless_char; /* Symbol for the purpose of Vglyphless_char_display. */ static Lisp_Object Qglyphless_char_display; ------------------------------------------------------------ revno: 114509 committer: Glenn Morris branch nick: trunk timestamp: Thu 2013-10-03 06:17:43 -0400 message: Auto-commit of generated files. diff: === modified file 'autogen/Makefile.in' --- autogen/Makefile.in 2013-09-09 10:17:42 +0000 +++ autogen/Makefile.in 2013-10-03 10:17:43 +0000 @@ -1017,6 +1017,7 @@ REPLACE_GETCWD = @REPLACE_GETCWD@ REPLACE_GETDELIM = @REPLACE_GETDELIM@ REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@ +REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@ REPLACE_GETGROUPS = @REPLACE_GETGROUPS@ REPLACE_GETLINE = @REPLACE_GETLINE@ REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ @@ -2720,6 +2721,7 @@ @BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ @BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ @BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ +@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \ @BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ @BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ @BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ === modified file 'autogen/config.in' --- autogen/config.in 2013-09-23 10:17:40 +0000 +++ autogen/config.in 2013-10-03 10:17:43 +0000 @@ -867,6 +867,9 @@ /* Define to 1 if you have the `sendto' function. */ #undef HAVE_SENDTO +/* Define to 1 if you have the `setdtablesize' function. */ +#undef HAVE_SETDTABLESIZE + /* Define to 1 if you have the `setitimer' function. */ #undef HAVE_SETITIMER === modified file 'autogen/configure' --- autogen/configure 2013-09-25 10:17:46 +0000 +++ autogen/configure 2013-10-03 10:17:43 +0000 @@ -1147,6 +1147,7 @@ REPLACE_GETPAGESIZE REPLACE_GETGROUPS REPLACE_GETLOGIN_R +REPLACE_GETDTABLESIZE REPLACE_GETDOMAINNAME REPLACE_GETCWD REPLACE_FTRUNCATE @@ -18182,6 +18183,7 @@ REPLACE_FTRUNCATE=0; REPLACE_GETCWD=0; REPLACE_GETDOMAINNAME=0; + REPLACE_GETDTABLESIZE=0; REPLACE_GETLOGIN_R=0; REPLACE_GETGROUPS=0; REPLACE_GETPAGESIZE=0; @@ -22659,9 +22661,11 @@ /* Many gnulib modules require POSIX conformance of EBADF. */ if (dup2 (2, 1000000) == -1 && errno != EBADF) result |= 16; - /* Flush out a cygwin core dump. */ + /* Flush out some cygwin core dumps. */ if (dup2 (2, -1) != -1 || errno != EBADF) result |= 32; + dup2 (2, 255); + dup2 (2, 256); return result; ; @@ -22686,6 +22690,17 @@ *yes) ;; *) REPLACE_DUP2=1 + for ac_func in setdtablesize +do : + ac_fn_c_check_func "$LINENO" "setdtablesize" "ac_cv_func_setdtablesize" +if test "x$ac_cv_func_setdtablesize" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SETDTABLESIZE 1 +_ACEOF + +fi +done + ;; esac fi @@ -28236,11 +28251,62 @@ - if test $ac_cv_func_getdtablesize != yes; then + + if test $ac_cv_func_getdtablesize = yes; then + # Cygwin 1.7.25 automatically increases the RLIMIT_NOFILE soft limit + # up to an unchangeable hard limit; all other platforms correctly + # require setrlimit before getdtablesize() can report a larger value. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getdtablesize works" >&5 +$as_echo_n "checking whether getdtablesize works... " >&6; } +if test "${gl_cv_func_getdtablesize_works+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + case "$host_os" in + cygwin*) # on cygwin 1.5.25, getdtablesize() automatically grows + gl_cv_func_getdtablesize_works="guessing no" ;; + *) gl_cv_func_getdtablesize_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include +int +main () +{ +int size = getdtablesize(); + if (dup2 (0, getdtablesize()) != -1) + return 1; + if (size != getdtablesize()) + return 2; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gl_cv_func_getdtablesize_works=yes +else + gl_cv_func_getdtablesize_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_getdtablesize_works" >&5 +$as_echo "$gl_cv_func_getdtablesize_works" >&6; } + case "$gl_cv_func_getdtablesize_works" in + *yes) ;; + *) REPLACE_GETDTABLESIZE=1 ;; + esac + else HAVE_GETDTABLESIZE=0 fi - if test $HAVE_GETDTABLESIZE = 0; then + if test $HAVE_GETDTABLESIZE = 0 || test $REPLACE_GETDTABLESIZE = 1; then ------------------------------------------------------------ revno: 114508 committer: Daiki Ueno branch nick: trunk timestamp: Thu 2013-10-03 16:11:27 +0900 message: Add support for package signature checking. * lisp/emacs-lisp/package.el (url-http-file-exists-p) (epg-make-context, epg-context-set-home-directory) (epg-verify-string, epg-context-result-for) (epg-signature-status, epg-signature-to-string) (epg-check-configuration, epg-configuration) (epg-import-keys-from-file): Declare. (package-check-signature): New user option. (package-unsigned-archives): New user option. (package-desc): Add `signed' field. (package-load-descriptor): Set `signed' field if .signed file exists. (package--archive-file-exists-p): New function. (package--check-signature): New function. (package-install-from-archive): Check package signature. (package--download-one-archive): Check archive signature. (package-delete): Remove .signed file. (package-import-keyring): New command. (package-refresh-contents): Import default keyring. (package-desc-status): Add "unsigned" status. (describe-package-1, package-menu--print-info) (package-menu-mark-delete, package-menu--find-upgrades) (package-menu--status-predicate): Support "unsigned" status. * test/automated/data/package/signed/archive-contents: * test/automated/data/package/signed/archive-contents.sig: * test/automated/data/package/signed/signed-good-1.0.el: * test/automated/data/package/signed/signed-good-1.0.el.sig: * test/automated/data/package/signed/signed-bad-1.0.el: * test/automated/data/package/signed/signed-bad-1.0.el.sig: * test/automated/data/package/key.pub: * test/automated/data/package/key.sec: New files. * test/automated/package-test.el (package-test-update-listing) (package-test-update-archives, package-test-describe-package): Adjust to package.el change. (package-test-signed): New test. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-10-03 04:58:56 +0000 +++ lisp/ChangeLog 2013-10-03 07:11:27 +0000 @@ -1,3 +1,28 @@ +2013-10-03 Daiki Ueno + + Add support for package signature checking. + * emacs-lisp/package.el (url-http-file-exists-p) + (epg-make-context, epg-context-set-home-directory) + (epg-verify-string, epg-context-result-for) + (epg-signature-status, epg-signature-to-string) + (epg-check-configuration, epg-configuration) + (epg-import-keys-from-file): Declare. + (package-check-signature): New user option. + (package-unsigned-archives): New user option. + (package-desc): Add `signed' field. + (package-load-descriptor): Set `signed' field if .signed file exists. + (package--archive-file-exists-p): New function. + (package--check-signature): New function. + (package-install-from-archive): Check package signature. + (package--download-one-archive): Check archive signature. + (package-delete): Remove .signed file. + (package-import-keyring): New command. + (package-refresh-contents): Import default keyring. + (package-desc-status): Add "unsigned" status. + (describe-package-1, package-menu--print-info) + (package-menu-mark-delete, package-menu--find-upgrades) + (package-menu--status-predicate): Support "unsigned" status. + 2013-10-03 Stefan Monnier * emacs-lisp/cconv.el (cconv-convert, cconv-analyse-form): Adjust for === modified file 'lisp/emacs-lisp/package.el' --- lisp/emacs-lisp/package.el 2013-10-01 15:52:53 +0000 +++ lisp/emacs-lisp/package.el 2013-10-03 07:11:27 +0000 @@ -206,6 +206,7 @@ (defvar Info-directory-list) (declare-function info-initialize "info" ()) (declare-function url-http-parse-response "url-http" ()) +(declare-function url-http-file-exists-p "url-http" (url)) (declare-function lm-header "lisp-mnt" (header)) (declare-function lm-commentary "lisp-mnt" (&optional file)) (defvar url-http-end-of-headers) @@ -285,6 +286,22 @@ :group 'package :version "24.1") +(defcustom package-check-signature 'allow-unsigned + "Whether to check package signatures when installing." + :type '(choice (const nil :tag "Never") + (const allow-unsigned :tag "Allow unsigned") + (const t :tag "Check always")) + :risky t + :group 'package + :version "24.1") + +(defcustom package-unsigned-archives nil + "A list of archives which do not use package signature." + :type '(repeat (string :tag "Archive name")) + :risky t + :group 'package + :version "24.1") + (defvar package--default-summary "No description available.") (cl-defstruct (package-desc @@ -340,7 +357,9 @@ `dir' The directory where the package is installed (if installed), `builtin' if it is built-in, or nil otherwise. -`extras' Optional alist of additional keyword-value pairs." +`extras' Optional alist of additional keyword-value pairs. + +`signed' Flag to indicate that the package is signed by provider." name version (summary package--default-summary) @@ -348,7 +367,8 @@ kind archive dir - extras) + extras + signed) ;; Pseudo fields. (defun package-desc-full-name (pkg-desc) @@ -428,7 +448,8 @@ (defun package-load-descriptor (pkg-dir) "Load the description file in directory PKG-DIR." (let ((pkg-file (expand-file-name (package--description-file pkg-dir) - pkg-dir))) + pkg-dir)) + (signed-file (concat pkg-dir ".signed"))) (when (file-exists-p pkg-file) (with-temp-buffer (insert-file-contents pkg-file) @@ -436,6 +457,8 @@ (let ((pkg-desc (package-process-define-package (read (current-buffer)) pkg-file))) (setf (package-desc-dir pkg-desc) pkg-dir) + (if (file-exists-p signed-file) + (setf (package-desc-signed pkg-desc) t)) pkg-desc))))) (defun package-load-all-descriptors () @@ -766,13 +789,87 @@ (error "Error during download request:%s" (buffer-substring-no-properties (point) (line-end-position)))))) +(defun package--archive-file-exists-p (location file) + (let ((http (string-match "\\`https?:" location))) + (if http + (progn + (require 'url-http) + (url-http-file-exists-p (concat location file))) + (file-exists-p (expand-file-name file location))))) + +(declare-function epg-make-context "epg" + (&optional protocol armor textmode include-certs + cipher-algorithm + digest-algorithm + compress-algorithm)) +(declare-function epg-context-set-home-directory "epg" (context directory)) +(declare-function epg-verify-string "epg" (context signature + &optional signed-text)) +(declare-function epg-context-result-for "epg" (context name)) +(declare-function epg-signature-status "epg" (signature)) +(declare-function epg-signature-to-string "epg" (signature)) + +(defun package--check-signature (location file) + "Check signature of the current buffer. +GnuPG keyring is located under \"gnupg\" in `package-user-dir'." + (let ((context (epg-make-context 'OpenPGP)) + (homedir (expand-file-name "gnupg" package-user-dir)) + (sig-file (concat file ".sig")) + sig-content + good-signatures) + (condition-case-unless-debug error + (setq sig-content (package--with-work-buffer location sig-file + (buffer-string))) + (error "Failed to download %s: %S" sig-file (cdr error))) + (epg-context-set-home-directory context homedir) + (epg-verify-string context sig-content (buffer-string)) + ;; The .sig file may contain multiple signatures. Success if one + ;; of the signatures is good. + (setq good-signatures + (delq nil (mapcar (lambda (sig) + (if (eq (epg-signature-status sig) 'good) + sig)) + (epg-context-result-for context 'verify)))) + (if (null good-signatures) + (error "Failed to verify signature %s: %S" + sig-file + (mapcar #'epg-signature-to-string + (epg-context-result-for context 'verify))) + good-signatures))) + (defun package-install-from-archive (pkg-desc) "Download and install a tar package." - (let ((location (package-archive-base pkg-desc)) - (file (concat (package-desc-full-name pkg-desc) - (package-desc-suffix pkg-desc)))) + (let* ((location (package-archive-base pkg-desc)) + (file (concat (package-desc-full-name pkg-desc) + (package-desc-suffix pkg-desc))) + (sig-file (concat file ".sig")) + good-signatures pkg-descs) (package--with-work-buffer location file - (package-unpack pkg-desc)))) + (if (and package-check-signature + (not (member (package-desc-archive pkg-desc) + package-unsigned-archives))) + (if (package--archive-file-exists-p location sig-file) + (setq good-signatures (package--check-signature location file)) + (unless (eq package-check-signature 'allow-unsigned) + (error "Unsigned package: `%s'" + (package-desc-name pkg-desc))))) + (package-unpack pkg-desc)) + ;; Here the package has been installed successfully, mark it as + ;; signed if appropriate. + (when good-signatures + ;; Write out good signatures into NAME-VERSION.signed file. + (write-region (mapconcat #'epg-signature-to-string good-signatures "\n") + nil + (expand-file-name + (concat (package-desc-full-name pkg-desc) + ".signed") + package-user-dir)) + ;; Update the old pkg-desc which will be shown on the description buffer. + (setf (package-desc-signed pkg-desc) t) + ;; Update the new (activated) pkg-desc as well. + (setq pkg-descs (cdr (assq (package-desc-name pkg-desc) package-alist))) + (if pkg-descs + (setf (package-desc-signed (car pkg-descs)) t))))) (defvar package--initialized nil) @@ -1104,6 +1201,10 @@ (error "Package `%s' is a system package, not deleting" (package-desc-full-name pkg-desc)) (delete-directory dir t t) + ;; Remove NAME-VERSION.signed file. + (let ((signed-file (concat dir ".signed"))) + (if (file-exists-p signed-file) + (delete-file signed-file))) ;; Update package-alist. (let* ((name (package-desc-name pkg-desc))) (delete pkg-desc (assq name package-alist))) @@ -1118,16 +1219,50 @@ ARCHIVE should be a cons cell of the form (NAME . LOCATION), similar to an entry in `package-alist'. Save the cached copy to \"archives/NAME/archive-contents\" in `package-user-dir'." - (let* ((dir (expand-file-name (format "archives/%s" (car archive)) - package-user-dir))) + (let ((dir (expand-file-name (format "archives/%s" (car archive)) + package-user-dir)) + (sig-file (concat file ".sig")) + good-signatures) (package--with-work-buffer (cdr archive) file + ;; Check signature of archive-contents, if desired. + (if (and package-check-signature + (not (member archive package-unsigned-archives))) + (if (package--archive-file-exists-p (cdr archive) sig-file) + (setq good-signatures (package--check-signature (cdr archive) + file)) + (unless (eq package-check-signature 'allow-unsigned) + (error "Unsigned archive `%s'" + (car archive))))) ;; Read the retrieved buffer to make sure it is valid (e.g. it ;; may fetch a URL redirect page). (when (listp (read buffer)) (make-directory dir t) (setq buffer-file-name (expand-file-name file dir)) (let ((version-control 'never)) - (save-buffer)))))) + (save-buffer)))) + (when good-signatures + ;; Write out good signatures into archive-contents.signed file. + (write-region (mapconcat #'epg-signature-to-string good-signatures "\n") + nil + (expand-file-name (concat file ".signed") dir))))) + +(declare-function epg-check-configuration "epg-config" + (config &optional minimum-version)) +(declare-function epg-configuration "epg-config" ()) +(declare-function epg-import-keys-from-file "epg" (context keys)) + +;;;###autoload +(defun package-import-keyring (&optional file) + "Import keys from FILE." + (interactive "fFile: ") + (setq file (expand-file-name file)) + (let ((context (epg-make-context 'OpenPGP)) + (homedir (expand-file-name "gnupg" package-user-dir))) + (make-directory homedir t) + (epg-context-set-home-directory context homedir) + (message "Importing %s..." (file-name-nondirectory file)) + (epg-import-keys-from-file context file) + (message "Importing %s...done" (file-name-nondirectory file)))) ;;;###autoload (defun package-refresh-contents () @@ -1138,6 +1273,14 @@ ;; FIXME: Do it asynchronously. (unless (file-exists-p package-user-dir) (make-directory package-user-dir t)) + (let ((default-keyring (expand-file-name "package-keyring.gpg" + data-directory))) + (if (file-exists-p default-keyring) + (condition-case-unless-debug error + (progn + (epg-check-configuration (epg-configuration)) + (package-import-keyring default-keyring)) + (error (message "Cannot import default keyring: %S" (cdr error)))))) (dolist (archive package-archives) (condition-case-unless-debug nil (package--download-one-archive archive "archive-contents") @@ -1209,7 +1352,8 @@ (homepage (if desc (cdr (assoc :url (package-desc-extras desc))))) (built-in (eq pkg-dir 'builtin)) (installable (and archive (not built-in))) - (status (if desc (package-desc-status desc) "orphan"))) + (status (if desc (package-desc-status desc) "orphan")) + (signed (if desc (package-desc-signed desc)))) (prin1 name) (princ " is ") (princ (if (memq (aref status 0) '(?a ?e ?i ?o ?u)) "an " "a ")) @@ -1222,7 +1366,9 @@ 'font-lock-face 'font-lock-builtin-face) ".")) (pkg-dir - (insert (propertize (capitalize status) ;FIXME: Why comment-face? + (insert (propertize (if (equal status "unsigned") + "Installed" + (capitalize status)) ;FIXME: Why comment-face? 'font-lock-face 'font-lock-comment-face)) (insert " in `") ;; Todo: Add button for uninstalling. @@ -1233,9 +1379,11 @@ (not (package-built-in-p name version))) (insert "',\n shadowing a " (propertize "built-in package" - 'font-lock-face 'font-lock-builtin-face) - ".") - (insert "'."))) + 'font-lock-face 'font-lock-builtin-face)) + (insert "'")) + (if signed + (insert ".") + (insert " (unsigned)."))) (installable (insert (capitalize status)) (insert " from " (format "%s" archive)) @@ -1449,7 +1597,8 @@ (dir (package-desc-dir pkg-desc)) (lle (assq name package-load-list)) (held (cadr lle)) - (version (package-desc-version pkg-desc))) + (version (package-desc-version pkg-desc)) + (signed (package-desc-signed pkg-desc))) (cond ((eq dir 'builtin) "built-in") ((and lle (null held)) "disabled") @@ -1463,7 +1612,9 @@ (dir ;One of the installed packages. (cond ((not (file-exists-p (package-desc-dir pkg-desc))) "deleted") - ((eq pkg-desc (cadr (assq name package-alist))) "installed") + ((eq pkg-desc (cadr (assq name package-alist))) (if signed + "installed" + "unsigned")) (t "obsolete"))) (t (let* ((ins (cadr (assq name package-alist))) @@ -1473,7 +1624,9 @@ (if (memq name package-menu--new-package-list) "new" "available")) ((version-list-< version ins-v) "obsolete") - ((version-list-= version ins-v) "installed"))))))) + ((version-list-= version ins-v) (if signed + "installed" + "unsigned")))))))) (defun package-menu--refresh (&optional packages) "Re-populate the `tabulated-list-entries'. @@ -1532,6 +1685,7 @@ (`"held" 'font-lock-constant-face) (`"disabled" 'font-lock-warning-face) (`"installed" 'font-lock-comment-face) + (`"unsigned" 'font-lock-warning-face) (_ 'font-lock-warning-face)))) ; obsolete. (list pkg-desc (vector (list (symbol-name (package-desc-name pkg-desc)) @@ -1570,7 +1724,7 @@ (defun package-menu-mark-delete (&optional _num) "Mark a package for deletion and move to the next line." (interactive "p") - (if (member (package-menu-get-status) '("installed" "obsolete")) + (if (member (package-menu-get-status) '("installed" "obsolete" "unsigned")) (tabulated-list-put-tag "D" t) (forward-line))) @@ -1624,7 +1778,7 @@ ;; ENTRY is (PKG-DESC [NAME VERSION STATUS DOC]) (let ((pkg-desc (car entry)) (status (aref (cadr entry) 2))) - (cond ((equal status "installed") + (cond ((member status '("installed" "unsigned")) (push pkg-desc installed)) ((member status '("available" "new")) (push (cons (package-desc-name pkg-desc) pkg-desc) @@ -1738,6 +1892,8 @@ ((string= sB "available") nil) ((string= sA "installed") t) ((string= sB "installed") nil) + ((string= sA "unsigned") t) + ((string= sB "unsigned") nil) ((string= sA "held") t) ((string= sB "held") nil) ((string= sA "built-in") t) === modified file 'test/ChangeLog' --- test/ChangeLog 2013-10-01 01:38:37 +0000 +++ test/ChangeLog 2013-10-03 07:11:27 +0000 @@ -1,3 +1,19 @@ +2013-10-03 Daiki Ueno + + * automated/data/package/signed/archive-contents: + * automated/data/package/signed/archive-contents.sig: + * automated/data/package/signed/signed-good-1.0.el: + * automated/data/package/signed/signed-good-1.0.el.sig: + * automated/data/package/signed/signed-bad-1.0.el: + * automated/data/package/signed/signed-bad-1.0.el.sig: + * automated/data/package/key.pub: + * automated/data/package/key.sec: New files. + + * automated/package-test.el (package-test-update-listing) + (package-test-update-archives, package-test-describe-package): + Adjust to package.el change. + (package-test-signed): New test. + 2013-10-01 Dmitry Gutov * automated/package-test.el: Update all cases to use :url instead === added file 'test/automated/data/package/key.pub' --- test/automated/data/package/key.pub 1970-01-01 00:00:00 +0000 +++ test/automated/data/package/key.pub 2013-10-03 07:11:27 +0000 @@ -0,0 +1,18 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.14 (GNU/Linux) + +mQENBFJNB8gBCACfbtpvYrM8V1HM0KFlIwatcEJugHqwOHpr/Z9mrCW0fxyQAW/d +2L+3QVNsN9Tz/K9lLcBUgeR7rhVEzHNqhmhNj/HnikwGqXbIofhp+QbZmBKnAlCz +d77kg8K9lozHtfTkm1gX/7DdPzQKmgi7WOzzi2395wGubeqJLvYaEcqVbI0Eob+E +3CzRjNy/e/Tf3TJRW5etTcdZN6LVuIY7tNCHqlQZTwyycON/hfLTX6cLCnzDsqm/ +NxCuwn9aqP9aGRGfIu7Y+If3zTymvrXEPUN98OEID814bOKdx0uVTZRiSMbvuTGI +8uMa/kpGX/78rqI61gbZV51RFoU7pT2tzwY/ABEBAAG0HkouIFIuIEhhY2tlciA8 +anJoQGV4YW1wbGUuY29tPokBOAQTAQIAIgUCUk0HyAIbAwYLCQgHAwIGFQgCCQoL +BBYCAwECHgECF4AACgkQtpVAhgkYletuhQf+JAyHYhTZNxjq0UYlikuLX8EtYbXX +PB+03J0B73SMzEai5XsiTU2ADxqxwr7pveVK1INf+IGLiiXBlQq+4DSOvQY4xLfp +58jTOYRV1ECvlXK/JtvVOwufXREADaydf9l/MUxA5G2PPBWIuQknh3ysPSsx68OJ +SzNHFwklLn0DKc4WloE/GLDpTzimnCg7QGzuUo3Iilpjdy8EvTdI5d3jx/mGJIwI +goB+YZgyxSPM+GjDwh5DEwD7OexNqqa7RynnmU0epmlYyi9UufCHLwgiiEIzjpWi +6+iF+CQ45ZAKncovByenIUv73J3ImOudrsskeAHBmahljv1he6uV9Egj2Q== +=b5Kg +-----END PGP PUBLIC KEY BLOCK----- === added file 'test/automated/data/package/key.sec' --- test/automated/data/package/key.sec 1970-01-01 00:00:00 +0000 +++ test/automated/data/package/key.sec 2013-10-03 07:11:27 +0000 @@ -0,0 +1,33 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v1.4.14 (GNU/Linux) + +lQO+BFJNB8gBCACfbtpvYrM8V1HM0KFlIwatcEJugHqwOHpr/Z9mrCW0fxyQAW/d +2L+3QVNsN9Tz/K9lLcBUgeR7rhVEzHNqhmhNj/HnikwGqXbIofhp+QbZmBKnAlCz +d77kg8K9lozHtfTkm1gX/7DdPzQKmgi7WOzzi2395wGubeqJLvYaEcqVbI0Eob+E +3CzRjNy/e/Tf3TJRW5etTcdZN6LVuIY7tNCHqlQZTwyycON/hfLTX6cLCnzDsqm/ +NxCuwn9aqP9aGRGfIu7Y+If3zTymvrXEPUN98OEID814bOKdx0uVTZRiSMbvuTGI +8uMa/kpGX/78rqI61gbZV51RFoU7pT2tzwY/ABEBAAH+AwMCKCCpPNXkXuVgF7cz +eByuvgIO7wImDYGOdJqsASSzV4q0u1acnGtlxg7WphKDF9RnC5+1ZZ1ZcrBcv2uJ +xZm2jHdjqM3FmgQTN70GVzO1nKEur2wxlKotG4Q+8BtaRDwHdKpQFk+QW9aInH3C +BkNWTK97iFwZaoUGxKuRJb35qjMe3SsDE7kdbtOqO+tOeppRVeOOZCn7F33ir/6i +j2gmIME6LFDzvBi6YAyMBSh90Ak70HJINt0QfXlZf5MtX1NaxaEcnsRmwwcNqxh9 +JvcC9q4WrR92NhHCHI+lOsAe7hbwo/VkwRjSSx0HdKkx6kvdcNj/9LeX/jykzLvg +kEqvAqT4Jmk57W2seqvpNcAO+eUVrJ5D1OR6khsUtikPp2pQH5MDXJDGcie+ZAFb +w6BwoWBDBjooKtfuP0LKqrdtJG2JLe6yhBhWvfqHPBlUU1SsA7a5aTCLo8FiqgEI +Kyy60zMx/2Mi48oN1a/mAoV1MTWLhOVUWJlIHM7nVLj1OaX0316LcLX/uTLTq40p +apHKwERanzY7f8ROiv/Fa/J+9cCsfOLKfjFAjpBVUVoOb39HsyS/vvkGMY4kgaD6 +K6r9JPdsaoYvsLkxk5HyHF7Mk2uS1z1EIArD2/3lRiX6ag+IU1Nl3XDkgfZj06K3 +juS84dGF8CmN49uOEjzAJAQZH9jTs5OKzUuZhGJF+gt0L78vLOoKRr8bu1N1GPqU +wnS908HWruXzjJl1CAhnuCa8FnDaU+tmEKjYpWuelx85kolpMW7LT5gOFZr84MIj +Kq3Rt2hU6qQ7Cdy1ep531YKkmyh9Y4l/Tgir1OtnQQqtNuwHI497l7qAUnKZBBHZ +guApjS9BoHsRXkw2mgDssZ+khOwj/xJm876nFSiQeCD0aIbU/4zJ9e2HUOJAZI1r +d7QeSi4gUi4gSGFja2VyIDxqcmhAZXhhbXBsZS5jb20+iQE4BBMBAgAiBQJSTQfI +AhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRC2lUCGCRiV626FB/4kDIdi +FNk3GOrRRiWKS4tfwS1htdc8H7TcnQHvdIzMRqLleyJNTYAPGrHCvum95UrUg1/4 +gYuKJcGVCr7gNI69BjjEt+nnyNM5hFXUQK+Vcr8m29U7C59dEQANrJ1/2X8xTEDk +bY88FYi5CSeHfKw9KzHrw4lLM0cXCSUufQMpzhaWgT8YsOlPOKacKDtAbO5SjciK +WmN3LwS9N0jl3ePH+YYkjAiCgH5hmDLFI8z4aMPCHkMTAPs57E2qprtHKeeZTR6m +aVjKL1S58IcvCCKIQjOOlaLr6IX4JDjlkAqdyi8HJ6chS/vcnciY652uyyR4AcGZ +qGWO/WF7q5X0SCPZ +=5FZK +-----END PGP PRIVATE KEY BLOCK----- === added directory 'test/automated/data/package/signed' === added file 'test/automated/data/package/signed/archive-contents' --- test/automated/data/package/signed/archive-contents 1970-01-01 00:00:00 +0000 +++ test/automated/data/package/signed/archive-contents 2013-10-03 07:11:27 +0000 @@ -0,0 +1,7 @@ +(1 + (signed-good . + [(1 0) + nil "A package with good signature" single]) + (signed-bad . + [(1 0) + nil "A package with bad signature" single])) === added file 'test/automated/data/package/signed/archive-contents.sig' Binary files test/automated/data/package/signed/archive-contents.sig 1970-01-01 00:00:00 +0000 and test/automated/data/package/signed/archive-contents.sig 2013-10-03 07:11:27 +0000 differ === added file 'test/automated/data/package/signed/signed-bad-1.0.el' --- test/automated/data/package/signed/signed-bad-1.0.el 1970-01-01 00:00:00 +0000 +++ test/automated/data/package/signed/signed-bad-1.0.el 2013-10-03 07:11:27 +0000 @@ -0,0 +1,33 @@ +;;; signed-bad.el --- A single-file package with bad signature + +;; Author: J. R. Hacker +;; Version: 1.0 +;; Keywords: frobnicate +;; URL: http://doodles.au + +;;; Commentary: + +;; This package provides a minor mode to frobnicate and/or bifurcate +;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly" +;; and all your dreams will come true. + +;;; Code: + +(defgroup signed-bad nil "Simply a file" + :group 'lisp) + +(defcustom signed-bad-super-sunday t + "How great is this?" + :type 'boolean + :group 'signed-bad) + +(defvar signed-bad-sudo-sandwich nil + "Make a sandwich?") + +;;;###autoload +(define-minor-mode signed-bad-mode + "It does good things to stuff") + +(provide 'signed-bad) + +;;; signed-bad.el ends here === added file 'test/automated/data/package/signed/signed-bad-1.0.el.sig' Binary files test/automated/data/package/signed/signed-bad-1.0.el.sig 1970-01-01 00:00:00 +0000 and test/automated/data/package/signed/signed-bad-1.0.el.sig 2013-10-03 07:11:27 +0000 differ === added file 'test/automated/data/package/signed/signed-good-1.0.el' --- test/automated/data/package/signed/signed-good-1.0.el 1970-01-01 00:00:00 +0000 +++ test/automated/data/package/signed/signed-good-1.0.el 2013-10-03 07:11:27 +0000 @@ -0,0 +1,33 @@ +;;; signed-good.el --- A single-file package with good signature + +;; Author: J. R. Hacker +;; Version: 1.0 +;; Keywords: frobnicate +;; URL: http://doodles.au + +;;; Commentary: + +;; This package provides a minor mode to frobnicate and/or bifurcate +;; any flanges you desire. To activate it, type "C-M-r M-3 butterfly" +;; and all your dreams will come true. + +;;; Code: + +(defgroup signed-good nil "Simply a file" + :group 'lisp) + +(defcustom signed-good-super-sunday t + "How great is this?" + :type 'boolean + :group 'signed-good) + +(defvar signed-good-sudo-sandwich nil + "Make a sandwich?") + +;;;###autoload +(define-minor-mode signed-good-mode + "It does good things to stuff") + +(provide 'signed-good) + +;;; signed-good.el ends here === added file 'test/automated/data/package/signed/signed-good-1.0.el.sig' Binary files test/automated/data/package/signed/signed-good-1.0.el.sig 1970-01-01 00:00:00 +0000 and test/automated/data/package/signed/signed-good-1.0.el.sig 2013-10-03 07:11:27 +0000 differ === modified file 'test/automated/package-test.el' --- test/automated/package-test.el 2013-10-01 01:38:37 +0000 +++ test/automated/package-test.el 2013-10-03 07:11:27 +0000 @@ -254,7 +254,7 @@ (should (package-installed-p 'simple-single)) (switch-to-buffer "*Packages*") (goto-char (point-min)) - (should (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+installed" nil t)) + (should (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+unsigned" nil t)) (goto-char (point-min)) (should-not (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+\\(available\\|new\\)" nil t)) (kill-buffer buf)))) @@ -276,7 +276,7 @@ ;; New version should be available and old version should be installed (goto-char (point-min)) (should (re-search-forward "^\\s-+simple-single\\s-+1.4\\s-+new" nil t)) - (should (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+installed" nil t)) + (should (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+unsigned" nil t)) (goto-char (point-min)) (should (re-search-forward "^\\s-+new-pkg\\s-+1.0\\s-+\\(available\\|new\\)" nil t)) @@ -307,9 +307,9 @@ (with-fake-help-buffer (describe-package 'simple-single) (goto-char (point-min)) - (should (search-forward "simple-single is an installed package." nil t)) + (should (search-forward "simple-single is an unsigned package." nil t)) (should (search-forward - (format "Status: Installed in `%s/'." + (format "Status: Installed in `%s/' (unsigned)." (expand-file-name "simple-single-1.3" package-user-dir)) nil t)) (should (search-forward "Version: 1.3" nil t)) @@ -347,6 +347,37 @@ (should (search-forward "This is a bare-bones readme file for the multi-file" nil t))))) +(ert-deftest package-test-signed () + "Test verifying package signature." + :expected-result (condition-case nil + (progn + (epg-check-configuration (epg-configuration)) + :passed) + (error :failed)) + (let* ((keyring (expand-file-name "key.pub" package-test-data-dir)) + (package-test-data-dir + (expand-file-name "data/package/signed" package-test-file-dir))) + (with-package-test () + (package-initialize) + (package-import-keyring keyring) + (package-refresh-contents) + (should (package-install 'signed-good)) + (should-error (package-install 'signed-bad)) + ;; Check if the installed package status is updated. + (let ((buf (package-list-packages))) + (package-menu-refresh) + (should (re-search-forward "^\\s-+signed-good\\s-+1\\.0\\s-+installed" + nil t))) + ;; Check if the package description is updated. + (with-fake-help-buffer + (describe-package 'signed-good) + (goto-char (point-min)) + (should (search-forward "signed-good is an installed package." nil t)) + (should (search-forward + (format "Status: Installed in `%s/'." + (expand-file-name "signed-good-1.0" package-user-dir)) + nil t)))))) + (provide 'package-test) ;;; package-test.el ends here ------------------------------------------------------------ revno: 114507 committer: Paul Eggert branch nick: trunk timestamp: Thu 2013-10-03 00:06:52 -0700 message: Merge from gnulib. * src/conf_post.h (__has_builtin, assume): Remove; gnulib now does these. * src/lisp.h: Include , for 'assume'. This also incorpoprates: 2013-10-02 verify: new macro 'assume' 2013-09-26 dup2, dup3: work around another cygwin crasher 2013-09-26 getdtablesize: work around cygwin issue diff: === modified file 'ChangeLog' --- ChangeLog 2013-09-25 03:44:34 +0000 +++ ChangeLog 2013-10-03 07:06:52 +0000 @@ -1,3 +1,10 @@ +2013-10-03 Paul Eggert + + Merge from gnulib, incorporating: + 2013-10-02 verify: new macro 'assume' + 2013-09-26 dup2, dup3: work around another cygwin crasher + 2013-09-26 getdtablesize: work around cygwin issue + 2013-09-25 Paul Eggert Merge from gnulib, incorporating: === modified file 'lib/dup2.c' --- lib/dup2.c 2013-01-02 16:37:04 +0000 +++ lib/dup2.c 2013-10-03 07:06:52 +0000 @@ -96,7 +96,11 @@ /* On Linux kernels 2.6.26-2.6.29, dup2 (fd, fd) returns -EBADF. On Cygwin 1.5.x, dup2 (1, 1) returns 0. On Cygwin 1.7.17, dup2 (1, -1) dumps core. + On Cygwin 1.7.25, dup2 (1, 256) can dump core. On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC. */ +# if HAVE_SETDTABLESIZE + setdtablesize (desired_fd + 1); +# endif if (desired_fd < 0) fd = desired_fd; if (fd == desired_fd) === modified file 'lib/getdtablesize.c' --- lib/getdtablesize.c 2013-07-07 18:00:14 +0000 +++ lib/getdtablesize.c 2013-10-03 07:06:52 +0000 @@ -22,11 +22,11 @@ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ -#include - -#include "msvc-inval.h" - -#if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include + +# include "msvc-inval.h" + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER static int _setmaxstdio_nothrow (int newmax) { @@ -44,10 +44,11 @@ return result; } -# define _setmaxstdio _setmaxstdio_nothrow -#endif +# define _setmaxstdio _setmaxstdio_nothrow +# endif -/* Cache for the previous getdtablesize () result. */ +/* Cache for the previous getdtablesize () result. Safe to cache because + Windows also lacks setrlimit. */ static int dtablesize; int @@ -83,4 +84,24 @@ return dtablesize; } +#elif HAVE_GETDTABLESIZE + +# include +# undef getdtablesize + +int +rpl_getdtablesize(void) +{ + /* To date, this replacement is only compiled for Cygwin 1.7.25, + which auto-increased the RLIMIT_NOFILE soft limit until it + hits the compile-time constant hard limit of 3200. Although + that version of cygwin supported a child process inheriting + a smaller soft limit, the smaller limit is not enforced, so + we might as well just report the hard limit. */ + struct rlimit lim; + if (!getrlimit (RLIMIT_NOFILE, &lim) && lim.rlim_max != RLIM_INFINITY) + return lim.rlim_max; + return getdtablesize (); +} + #endif === modified file 'lib/gnulib.mk' --- lib/gnulib.mk 2013-08-04 16:56:56 +0000 +++ lib/gnulib.mk 2013-10-03 07:06:52 +0000 @@ -1707,6 +1707,7 @@ -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ + -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ === modified file 'lib/unistd.in.h' --- lib/unistd.in.h 2013-09-19 21:40:08 +0000 +++ lib/unistd.in.h 2013-10-03 07:06:52 +0000 @@ -654,10 +654,19 @@ #if @GNULIB_GETDTABLESIZE@ /* Return the maximum number of file descriptors in the current process. In POSIX, this is same as sysconf (_SC_OPEN_MAX). */ -# if !@HAVE_GETDTABLESIZE@ +# if @REPLACE_GETDTABLESIZE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef getdtablesize +# define getdtablesize rpl_getdtablesize +# endif +_GL_FUNCDECL_RPL (getdtablesize, int, (void)); +_GL_CXXALIAS_RPL (getdtablesize, int, (void)); +# else +# if !@HAVE_GETDTABLESIZE@ _GL_FUNCDECL_SYS (getdtablesize, int, (void)); -# endif +# endif _GL_CXXALIAS_SYS (getdtablesize, int, (void)); +# endif _GL_CXXALIASWARN (getdtablesize); #elif defined GNULIB_POSIXCHECK # undef getdtablesize === modified file 'lib/verify.h' --- lib/verify.h 2013-07-08 06:15:38 +0000 +++ lib/verify.h 2013-10-03 07:06:52 +0000 @@ -250,6 +250,30 @@ #define verify(R) _GL_VERIFY (R, "verify (" #R ")") +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/* Assume that R always holds. This lets the compiler optimize + accordingly. R should not have side-effects; it may or may not be + evaluated. Behavior is undefined if R is false. */ + +#if (__has_builtin (__builtin_unreachable) \ + || 4 < __GNUC__ + (5 <= __GNUC_MINOR__)) +# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) +#elif 1200 <= _MSC_VER +# define assume(R) __assume (R) +#elif (defined lint \ + && (__has_builtin (__builtin_trap) \ + || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)))) + /* Doing it this way helps various packages when configured with + --enable-gcc-warnings, which compiles with -Dlint. It's nicer + when 'assume' silences warnings even with older GCCs. */ +# define assume(R) ((R) ? (void) 0 : __builtin_trap ()) +#else +# define assume(R) ((void) (0 && (R))) +#endif + /* @assert.h omit end@ */ #endif === modified file 'm4/dup2.m4' --- m4/dup2.m4 2013-01-02 16:37:04 +0000 +++ m4/dup2.m4 2013-10-03 07:06:52 +0000 @@ -1,4 +1,4 @@ -#serial 19 +#serial 20 dnl Copyright (C) 2002, 2005, 2007, 2009-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -39,9 +39,11 @@ /* Many gnulib modules require POSIX conformance of EBADF. */ if (dup2 (2, 1000000) == -1 && errno != EBADF) result |= 16; - /* Flush out a cygwin core dump. */ + /* Flush out some cygwin core dumps. */ if (dup2 (2, -1) != -1 || errno != EBADF) result |= 32; + dup2 (2, 255); + dup2 (2, 256); return result; ]) ], @@ -65,6 +67,7 @@ *yes) ;; *) REPLACE_DUP2=1 + AC_CHECK_FUNCS([setdtablesize]) ;; esac fi === modified file 'm4/getdtablesize.m4' --- m4/getdtablesize.m4 2013-07-07 18:00:14 +0000 +++ m4/getdtablesize.m4 2013-10-03 07:06:52 +0000 @@ -1,4 +1,4 @@ -# getdtablesize.m4 serial 4 +# getdtablesize.m4 serial 5 dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,8 +7,35 @@ AC_DEFUN([gl_FUNC_GETDTABLESIZE], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) AC_CHECK_FUNCS_ONCE([getdtablesize]) - if test $ac_cv_func_getdtablesize != yes; then + if test $ac_cv_func_getdtablesize = yes; then + # Cygwin 1.7.25 automatically increases the RLIMIT_NOFILE soft limit + # up to an unchangeable hard limit; all other platforms correctly + # require setrlimit before getdtablesize() can report a larger value. + AC_CACHE_CHECK([whether getdtablesize works], + [gl_cv_func_getdtablesize_works], + [AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[#include ]], + [int size = getdtablesize(); + if (dup2 (0, getdtablesize()) != -1) + return 1; + if (size != getdtablesize()) + return 2; + ])], + [gl_cv_func_getdtablesize_works=yes], + [gl_cv_func_getdtablesize_works=no], + [case "$host_os" in + cygwin*) # on cygwin 1.5.25, getdtablesize() automatically grows + gl_cv_func_getdtablesize_works="guessing no" ;; + *) gl_cv_func_getdtablesize_works="guessing yes" ;; + esac]) + ]) + case "$gl_cv_func_getdtablesize_works" in + *yes) ;; + *) REPLACE_GETDTABLESIZE=1 ;; + esac + else HAVE_GETDTABLESIZE=0 fi ]) === modified file 'm4/gnulib-comp.m4' --- m4/gnulib-comp.m4 2013-08-12 00:52:17 +0000 +++ m4/gnulib-comp.m4 2013-10-03 07:06:52 +0000 @@ -433,7 +433,7 @@ { if ! $gl_gnulib_enabled_getdtablesize; then gl_FUNC_GETDTABLESIZE - if test $HAVE_GETDTABLESIZE = 0; then + if test $HAVE_GETDTABLESIZE = 0 || test $REPLACE_GETDTABLESIZE = 1; then AC_LIBOBJ([getdtablesize]) gl_PREREQ_GETDTABLESIZE fi === modified file 'm4/unistd_h.m4' --- m4/unistd_h.m4 2013-01-02 16:37:04 +0000 +++ m4/unistd_h.m4 2013-10-03 07:06:52 +0000 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 66 +# unistd_h.m4 serial 67 dnl Copyright (C) 2006-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -160,6 +160,7 @@ REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) + REPLACE_GETDTABLESIZE=0; AC_SUBST([REPLACE_GETDTABLESIZE]) REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) REPLACE_GETGROUPS=0; AC_SUBST([REPLACE_GETGROUPS]) REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-03 06:31:06 +0000 +++ src/ChangeLog 2013-10-03 07:06:52 +0000 @@ -1,5 +1,9 @@ 2013-10-03 Paul Eggert + Adjust to merge from gnulib. + * conf_post.h (__has_builtin, assume): Remove; gnulib now does these. + * lisp.h: Include , for 'assume'. + * eval.c (clobbered_eassert): New macro. (internal_catch, internal_condition_case) (internal_condition_case_1, internal_condition_case_2) === modified file 'src/conf_post.h' --- src/conf_post.h 2013-09-24 04:28:06 +0000 +++ src/conf_post.h 2013-10-03 07:06:52 +0000 @@ -248,23 +248,6 @@ # define FLEXIBLE_ARRAY_MEMBER 1 #endif -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -/* Tell the compiler (and lint) that COND will always hold, and that - it should optimize (or check) accordingly. */ -#if (__has_builtin (__builtin_unreachable) \ - || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __GNUC__ > 4) -# define assume(cond) ((cond) ? (void) 0 : __builtin_unreachable ()) -#elif defined _MSC_VER -# define assume(cond) __assume (cond) -#elif defined lint -# define assume(cond) ((cond) ? (void) 0 : abort ()) -#else -# define assume(cond) ((void) (0 && (cond))) -#endif - /* Use this to suppress gcc's `...may be used before initialized' warnings. */ #ifdef lint /* Use CODE only if lint checking is in effect. */ === modified file 'src/lisp.h' --- src/lisp.h 2013-10-03 04:58:56 +0000 +++ src/lisp.h 2013-10-03 07:06:52 +0000 @@ -31,6 +31,7 @@ #include #include +#include INLINE_HEADER_BEGIN @@ -1145,9 +1146,9 @@ /* ...but sometimes there is also a pointer internally used in vector allocation code. Usually you don't want to touch this. */ struct Lisp_Vector *next; - + /* We can't use FLEXIBLE_ARRAY_MEMBER here. */ - Lisp_Object contents[1]; + Lisp_Object contents[1]; } u; }; ------------------------------------------------------------ revno: 114506 committer: Paul Eggert branch nick: trunk timestamp: Wed 2013-10-02 23:31:06 -0700 message: * eval.c (clobbered_eassert): New macro. (internal_catch, internal_condition_case) (internal_condition_case_1, internal_condition_case_2) (internal_condition_case_n): Use it instead of eassert when the argument contains locals clobbered by longjmp. Don't use clobbered locals outside of clobbered_eassert. (internal_lisp_condition_case): Use a volatile variable to work around a local variable's getting clobbered. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-10-03 04:58:56 +0000 +++ src/ChangeLog 2013-10-03 06:31:06 +0000 @@ -1,3 +1,14 @@ +2013-10-03 Paul Eggert + + * eval.c (clobbered_eassert): New macro. + (internal_catch, internal_condition_case) + (internal_condition_case_1, internal_condition_case_2) + (internal_condition_case_n): Use it instead of eassert + when the argument contains locals clobbered by longjmp. + Don't use clobbered locals outside of clobbered_eassert. + (internal_lisp_condition_case): Use a volatile variable + to work around a local variable's getting clobbered. + 2013-10-03 Stefan Monnier * lisp.h (struct handler): Merge struct handler and struct catchtag. === modified file 'src/eval.c' --- src/eval.c 2013-10-03 04:58:56 +0000 +++ src/eval.c 2013-10-03 06:31:06 +0000 @@ -1072,6 +1072,12 @@ return internal_catch (tag, Fprogn, XCDR (args)); } +/* Assert that E is true, as a comment only. Use this instead of + eassert (E) when E contains variables that might be clobbered by a + longjmp. */ + +#define clobbered_eassert(E) ((void) 0) + /* Set up a catch, then call C function FUNC on argument ARG. FUNC should return a Lisp_Object. This is how catches are done from within C code. */ @@ -1089,14 +1095,14 @@ if (! sys_setjmp (c->jmp)) { Lisp_Object val = (*func) (arg); - eassert (handlerlist == c); - handlerlist = c->next; + clobbered_eassert (handlerlist == c); + handlerlist = handlerlist->next; return val; } else { /* Throw works by a longjmp that comes right here. */ Lisp_Object val = handlerlist->val; - eassert (handlerlist == c); + clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; return val; } @@ -1252,6 +1258,7 @@ be added to handlerlist last. So we build in `clauses' a table that contains `handlers' but in reverse order. */ Lisp_Object *clauses = alloca (clausenb * sizeof (Lisp_Object *)); + Lisp_Object *volatile clauses_volatile = clauses; int i = clausenb; for (val = handlers; CONSP (val); val = XCDR (val)) clauses[--i] = XCAR (val); @@ -1266,7 +1273,7 @@ { ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object val = handlerlist->val; - Lisp_Object *chosen_clause = clauses; + Lisp_Object *chosen_clause = clauses_volatile; for (c = handlerlist->next; c != oldhandlerlist; c = c->next) chosen_clause++; handlerlist = oldhandlerlist; @@ -1316,14 +1323,14 @@ if (sys_setjmp (c->jmp)) { Lisp_Object val = handlerlist->val; - eassert (handlerlist == c); + clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; return (*hfun) (val); } val = (*bfun) (); - eassert (handlerlist == c); - handlerlist = c->next; + clobbered_eassert (handlerlist == c); + handlerlist = handlerlist->next; return val; } @@ -1340,14 +1347,14 @@ if (sys_setjmp (c->jmp)) { Lisp_Object val = handlerlist->val; - eassert (handlerlist == c); + clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; return (*hfun) (val); } val = (*bfun) (arg); - eassert (handlerlist == c); - handlerlist = c->next; + clobbered_eassert (handlerlist == c); + handlerlist = handlerlist->next; return val; } @@ -1368,14 +1375,14 @@ if (sys_setjmp (c->jmp)) { Lisp_Object val = handlerlist->val; - eassert (handlerlist == c); + clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; return (*hfun) (val); } val = (*bfun) (arg1, arg2); - eassert (handlerlist == c); - handlerlist = c->next; + clobbered_eassert (handlerlist == c); + handlerlist = handlerlist->next; return val; } @@ -1398,14 +1405,14 @@ if (sys_setjmp (c->jmp)) { Lisp_Object val = handlerlist->val; - eassert (handlerlist == c); + clobbered_eassert (handlerlist == c); handlerlist = handlerlist->next; return (*hfun) (val, nargs, args); } val = (*bfun) (nargs, args); - eassert (handlerlist == c); - handlerlist = c->next; + clobbered_eassert (handlerlist == c); + handlerlist = handlerlist->next; return val; }