aboutsummaryrefslogtreecommitdiffstats
path: root/src/fns.c
diff options
context:
space:
mode:
authorMichael R. Mauger2017-07-24 22:15:04 -0400
committerMichael R. Mauger2017-07-24 22:15:04 -0400
commitdf1a71272e5cdd10b511e2ffd702ca50ddd8a773 (patch)
tree9b9ac725394ee80891e2bff57b6407d0e491e71a /src/fns.c
parenteb27fc4d49e8c914cd0e6a8a2d02159601542141 (diff)
parent32daa3cb54523006c88717cbeac87964cd687a1b (diff)
downloademacs-df1a71272e5cdd10b511e2ffd702ca50ddd8a773.tar.gz
emacs-df1a71272e5cdd10b511e2ffd702ca50ddd8a773.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'src/fns.c')
-rw-r--r--src/fns.c160
1 files changed, 124 insertions, 36 deletions
diff --git a/src/fns.c b/src/fns.c
index 6610d2a6d0e..d849618f2b7 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -35,6 +35,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35#include "intervals.h" 35#include "intervals.h"
36#include "window.h" 36#include "window.h"
37#include "puresize.h" 37#include "puresize.h"
38#include "gnutls.h"
39
40#ifdef WINDOWSNT
41# define gnutls_rnd w32_gnutls_rnd
42#endif
38 43
39static void sort_vector_copy (Lisp_Object, ptrdiff_t, 44static void sort_vector_copy (Lisp_Object, ptrdiff_t,
40 Lisp_Object *restrict, Lisp_Object *restrict); 45 Lisp_Object *restrict, Lisp_Object *restrict);
@@ -1417,17 +1422,22 @@ assq_no_quit (Lisp_Object key, Lisp_Object list)
1417 return Qnil; 1422 return Qnil;
1418} 1423}
1419 1424
1420DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0, 1425DEFUN ("assoc", Fassoc, Sassoc, 2, 3, 0,
1421 doc: /* Return non-nil if KEY is `equal' to the car of an element of LIST. 1426 doc: /* Return non-nil if KEY is equal to the car of an element of LIST.
1422The value is actually the first element of LIST whose car equals KEY. */) 1427The value is actually the first element of LIST whose car equals KEY.
1423 (Lisp_Object key, Lisp_Object list) 1428
1429Equality is defined by TESTFN if non-nil or by `equal' if nil. */)
1430 (Lisp_Object key, Lisp_Object list, Lisp_Object testfn)
1424{ 1431{
1425 Lisp_Object tail = list; 1432 Lisp_Object tail = list;
1426 FOR_EACH_TAIL (tail) 1433 FOR_EACH_TAIL (tail)
1427 { 1434 {
1428 Lisp_Object car = XCAR (tail); 1435 Lisp_Object car = XCAR (tail);
1429 if (CONSP (car) 1436 if (CONSP (car)
1430 && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key)))) 1437 && (NILP (testfn)
1438 ? (EQ (XCAR (car), key) || !NILP (Fequal
1439 (XCAR (car), key)))
1440 : !NILP (call2 (testfn, XCAR (car), key))))
1431 return car; 1441 return car;
1432 } 1442 }
1433 CHECK_LIST_END (tail, list); 1443 CHECK_LIST_END (tail, list);
@@ -4735,22 +4745,42 @@ make_digest_string (Lisp_Object digest, int digest_size)
4735 return digest; 4745 return digest;
4736} 4746}
4737 4747
4738/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */ 4748DEFUN ("secure-hash-algorithms", Fsecure_hash_algorithms,
4749 Ssecure_hash_algorithms, 0, 0, 0,
4750 doc: /* Return a list of all the supported `secure_hash' algorithms. */)
4751 (void)
4752{
4753 return listn (CONSTYPE_HEAP, 6,
4754 Qmd5,
4755 Qsha1,
4756 Qsha224,
4757 Qsha256,
4758 Qsha384,
4759 Qsha512);
4760}
4739 4761
4740static Lisp_Object 4762/* Extract data from a string or a buffer. SPEC is a list of
4741secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, 4763(BUFFER-OR-STRING-OR-SYMBOL START END CODING-SYSTEM NOERROR) which behave as
4742 Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, 4764specified with `secure-hash' and in Info node
4743 Lisp_Object binary) 4765`(elisp)Format of GnuTLS Cryptography Inputs'. */
4766char *
4767extract_data_from_object (Lisp_Object spec,
4768 ptrdiff_t *start_byte,
4769 ptrdiff_t *end_byte)
4744{ 4770{
4745 ptrdiff_t size, start_char = 0, start_byte, end_char = 0, end_byte; 4771 Lisp_Object object = XCAR (spec);
4746 register EMACS_INT b, e;
4747 register struct buffer *bp;
4748 EMACS_INT temp;
4749 int digest_size;
4750 void *(*hash_func) (const char *, size_t, void *);
4751 Lisp_Object digest;
4752 4772
4753 CHECK_SYMBOL (algorithm); 4773 if (CONSP (spec)) spec = XCDR (spec);
4774 Lisp_Object start = CAR_SAFE (spec);
4775
4776 if (CONSP (spec)) spec = XCDR (spec);
4777 Lisp_Object end = CAR_SAFE (spec);
4778
4779 if (CONSP (spec)) spec = XCDR (spec);
4780 Lisp_Object coding_system = CAR_SAFE (spec);
4781
4782 if (CONSP (spec)) spec = XCDR (spec);
4783 Lisp_Object noerror = CAR_SAFE (spec);
4754 4784
4755 if (STRINGP (object)) 4785 if (STRINGP (object))
4756 { 4786 {
@@ -4778,23 +4808,24 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
4778 if (STRING_MULTIBYTE (object)) 4808 if (STRING_MULTIBYTE (object))
4779 object = code_convert_string (object, coding_system, Qnil, 1, 0, 1); 4809 object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
4780 4810
4781 size = SCHARS (object); 4811 ptrdiff_t size = SCHARS (object), start_char, end_char;
4782 validate_subarray (object, start, end, size, &start_char, &end_char); 4812 validate_subarray (object, start, end, size, &start_char, &end_char);
4783 4813
4784 start_byte = !start_char ? 0 : string_char_to_byte (object, start_char); 4814 *start_byte = !start_char ? 0 : string_char_to_byte (object, start_char);
4785 end_byte = (end_char == size 4815 *end_byte = (end_char == size
4786 ? SBYTES (object) 4816 ? SBYTES (object)
4787 : string_char_to_byte (object, end_char)); 4817 : string_char_to_byte (object, end_char));
4788 } 4818 }
4789 else 4819 else if (BUFFERP (object))
4790 { 4820 {
4791 struct buffer *prev = current_buffer; 4821 struct buffer *prev = current_buffer;
4822 EMACS_INT b, e;
4792 4823
4793 record_unwind_current_buffer (); 4824 record_unwind_current_buffer ();
4794 4825
4795 CHECK_BUFFER (object); 4826 CHECK_BUFFER (object);
4796 4827
4797 bp = XBUFFER (object); 4828 struct buffer *bp = XBUFFER (object);
4798 set_buffer_internal (bp); 4829 set_buffer_internal (bp);
4799 4830
4800 if (NILP (start)) 4831 if (NILP (start))
@@ -4814,7 +4845,11 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
4814 } 4845 }
4815 4846
4816 if (b > e) 4847 if (b > e)
4817 temp = b, b = e, e = temp; 4848 {
4849 EMACS_INT temp = b;
4850 b = e;
4851 e = temp;
4852 }
4818 4853
4819 if (!(BEGV <= b && e <= ZV)) 4854 if (!(BEGV <= b && e <= ZV))
4820 args_out_of_range (start, end); 4855 args_out_of_range (start, end);
@@ -4887,10 +4922,55 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
4887 4922
4888 if (STRING_MULTIBYTE (object)) 4923 if (STRING_MULTIBYTE (object))
4889 object = code_convert_string (object, coding_system, Qnil, 1, 0, 0); 4924 object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
4890 start_byte = 0; 4925 *start_byte = 0;
4891 end_byte = SBYTES (object); 4926 *end_byte = SBYTES (object);
4927 }
4928 else if (EQ (object, Qiv_auto))
4929 {
4930#ifdef HAVE_GNUTLS3
4931 /* Format: (iv-auto REQUIRED-LENGTH). */
4932
4933 if (! NATNUMP (start))
4934 error ("Without a length, `iv-auto' can't be used; see ELisp manual");
4935 else
4936 {
4937 EMACS_INT start_hold = XFASTINT (start);
4938 object = make_uninit_string (start_hold);
4939 gnutls_rnd (GNUTLS_RND_NONCE, SSDATA (object), start_hold);
4940
4941 *start_byte = 0;
4942 *end_byte = start_hold;
4943 }
4944#else
4945 error ("GnuTLS is not available, so `iv-auto' can't be used");
4946#endif
4892 } 4947 }
4893 4948
4949 return SSDATA (object);
4950}
4951
4952
4953/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */
4954
4955static Lisp_Object
4956secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
4957 Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror,
4958 Lisp_Object binary)
4959{
4960 ptrdiff_t start_byte, end_byte;
4961 int digest_size;
4962 void *(*hash_func) (const char *, size_t, void *);
4963 Lisp_Object digest;
4964
4965 CHECK_SYMBOL (algorithm);
4966
4967 Lisp_Object spec = list5 (object, start, end, coding_system, noerror);
4968
4969 const char *input = extract_data_from_object (spec, &start_byte, &end_byte);
4970
4971 if (input == NULL)
4972 error ("secure_hash: failed to extract data from object, aborting!");
4973
4894 if (EQ (algorithm, Qmd5)) 4974 if (EQ (algorithm, Qmd5))
4895 { 4975 {
4896 digest_size = MD5_DIGEST_SIZE; 4976 digest_size = MD5_DIGEST_SIZE;
@@ -4928,7 +5008,7 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start,
4928 hexified value */ 5008 hexified value */
4929 digest = make_uninit_string (digest_size * 2); 5009 digest = make_uninit_string (digest_size * 2);
4930 5010
4931 hash_func (SSDATA (object) + start_byte, 5011 hash_func (input + start_byte,
4932 end_byte - start_byte, 5012 end_byte - start_byte,
4933 SSDATA (digest)); 5013 SSDATA (digest));
4934 5014
@@ -4979,6 +5059,8 @@ The two optional arguments START and END are positions specifying for
4979which part of OBJECT to compute the hash. If nil or omitted, uses the 5059which part of OBJECT to compute the hash. If nil or omitted, uses the
4980whole OBJECT. 5060whole OBJECT.
4981 5061
5062The full list of algorithms can be obtained with `secure-hash-algorithms'.
5063
4982If BINARY is non-nil, returns a string in binary form. */) 5064If BINARY is non-nil, returns a string in binary form. */)
4983 (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary) 5065 (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
4984{ 5066{
@@ -5026,13 +5108,6 @@ disregarding any coding systems. If nil, use the current buffer. */ )
5026void 5108void
5027syms_of_fns (void) 5109syms_of_fns (void)
5028{ 5110{
5029 DEFSYM (Qmd5, "md5");
5030 DEFSYM (Qsha1, "sha1");
5031 DEFSYM (Qsha224, "sha224");
5032 DEFSYM (Qsha256, "sha256");
5033 DEFSYM (Qsha384, "sha384");
5034 DEFSYM (Qsha512, "sha512");
5035
5036 /* Hash table stuff. */ 5111 /* Hash table stuff. */
5037 DEFSYM (Qhash_table_p, "hash-table-p"); 5112 DEFSYM (Qhash_table_p, "hash-table-p");
5038 DEFSYM (Qeq, "eq"); 5113 DEFSYM (Qeq, "eq");
@@ -5069,6 +5144,18 @@ syms_of_fns (void)
5069 defsubr (&Smaphash); 5144 defsubr (&Smaphash);
5070 defsubr (&Sdefine_hash_table_test); 5145 defsubr (&Sdefine_hash_table_test);
5071 5146
5147 /* Crypto and hashing stuff. */
5148 DEFSYM (Qiv_auto, "iv-auto");
5149
5150 DEFSYM (Qmd5, "md5");
5151 DEFSYM (Qsha1, "sha1");
5152 DEFSYM (Qsha224, "sha224");
5153 DEFSYM (Qsha256, "sha256");
5154 DEFSYM (Qsha384, "sha384");
5155 DEFSYM (Qsha512, "sha512");
5156
5157 /* Miscellaneous stuff. */
5158
5072 DEFSYM (Qstring_lessp, "string-lessp"); 5159 DEFSYM (Qstring_lessp, "string-lessp");
5073 DEFSYM (Qprovide, "provide"); 5160 DEFSYM (Qprovide, "provide");
5074 DEFSYM (Qrequire, "require"); 5161 DEFSYM (Qrequire, "require");
@@ -5187,6 +5274,7 @@ this variable. */);
5187 defsubr (&Sbase64_encode_string); 5274 defsubr (&Sbase64_encode_string);
5188 defsubr (&Sbase64_decode_string); 5275 defsubr (&Sbase64_decode_string);
5189 defsubr (&Smd5); 5276 defsubr (&Smd5);
5277 defsubr (&Ssecure_hash_algorithms);
5190 defsubr (&Ssecure_hash); 5278 defsubr (&Ssecure_hash);
5191 defsubr (&Sbuffer_hash); 5279 defsubr (&Sbuffer_hash);
5192 defsubr (&Slocale_info); 5280 defsubr (&Slocale_info);