comparison src/fns.c @ 23690:5149f79d6dfd

(MAX_ALLOCA): New macro. (Fbase64_encode_region, Fbase64_encode_string, Fbase64_decode_region, Fbase64_decode_string): Don't allocate more than MAX_ALLOCA bytes with alloca; otherwise use xmalloc.
author Eli Zaretskii <eliz@gnu.org>
date Wed, 11 Nov 1998 11:12:09 +0000
parents e8bf0c9f869d
children e963fc8ca03f
comparison
equal deleted inserted replaced
23689:c0766cb586e4 23690:5149f79d6dfd
2750 #define IS_ASCII(Character) \ 2750 #define IS_ASCII(Character) \
2751 ((Character) < 128) 2751 ((Character) < 128)
2752 #define IS_BASE64(Character) \ 2752 #define IS_BASE64(Character) \
2753 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0) 2753 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
2754 2754
2755 /* Don't use alloca for regions larger than this, lest we overflow
2756 their stack. */
2757 #define MAX_ALLOCA 16*1024
2758
2755 /* Table of characters coding the 64 values. */ 2759 /* Table of characters coding the 64 values. */
2756 static char base64_value_to_char[64] = 2760 static char base64_value_to_char[64] =
2757 { 2761 {
2758 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */ 2762 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */
2759 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */ 2763 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
2829 characters, and then we round up. */ 2833 characters, and then we round up. */
2830 length = iend - ibeg; 2834 length = iend - ibeg;
2831 allength = length + length/3 + 1; 2835 allength = length + length/3 + 1;
2832 allength += allength / MIME_LINE_LENGTH + 1 + 6; 2836 allength += allength / MIME_LINE_LENGTH + 1 + 6;
2833 2837
2834 encoded = (char *) alloca (allength); 2838 if (allength <= MAX_ALLOCA)
2839 encoded = (char *) alloca (allength);
2840 else
2841 encoded = (char *) xmalloc (allength);
2835 encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length, 2842 encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length,
2836 NILP (no_line_break)); 2843 NILP (no_line_break));
2837 if (encoded_length > allength) 2844 if (encoded_length > allength)
2838 abort (); 2845 abort ();
2839 2846
2840 /* Now we have encoded the region, so we insert the new contents 2847 /* Now we have encoded the region, so we insert the new contents
2841 and delete the old. (Insert first in order to preserve markers.) */ 2848 and delete the old. (Insert first in order to preserve markers.) */
2842 SET_PT_BOTH (XFASTINT (beg), ibeg); 2849 SET_PT_BOTH (XFASTINT (beg), ibeg);
2843 insert (encoded, encoded_length); 2850 insert (encoded, encoded_length);
2851 if (allength > MAX_ALLOCA)
2852 free (encoded);
2844 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1); 2853 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
2845 2854
2846 /* If point was outside of the region, restore it exactly; else just 2855 /* If point was outside of the region, restore it exactly; else just
2847 move to the beginning of the region. */ 2856 move to the beginning of the region. */
2848 if (old_pos >= XFASTINT (end)) 2857 if (old_pos >= XFASTINT (end))
2861 (string) 2870 (string)
2862 Lisp_Object string; 2871 Lisp_Object string;
2863 { 2872 {
2864 int allength, length, encoded_length; 2873 int allength, length, encoded_length;
2865 char *encoded; 2874 char *encoded;
2875 Lisp_Object encoded_string;
2866 2876
2867 CHECK_STRING (string, 1); 2877 CHECK_STRING (string, 1);
2868 2878
2869 length = STRING_BYTES (XSTRING (string)); 2879 length = STRING_BYTES (XSTRING (string));
2870 allength = length + length/3 + 1 + 6; 2880 allength = length + length/3 + 1 + 6;
2871 2881
2872 /* We need to allocate enough room for decoding the text. */ 2882 /* We need to allocate enough room for decoding the text. */
2873 encoded = (char *) alloca (allength); 2883 if (allength <= MAX_ALLOCA)
2884 encoded = (char *) alloca (allength);
2885 else
2886 encoded = (char *) xmalloc (allength);
2874 2887
2875 encoded_length = base64_encode_1 (XSTRING (string)->data, 2888 encoded_length = base64_encode_1 (XSTRING (string)->data,
2876 encoded, length, 0); 2889 encoded, length, 0);
2877 if (encoded_length > allength) 2890 if (encoded_length > allength)
2878 abort (); 2891 abort ();
2879 2892
2880 return make_unibyte_string (encoded, encoded_length); 2893 encoded_string = make_unibyte_string (encoded, encoded_length);
2894 if (allength > MAX_ALLOCA)
2895 free (encoded);
2896
2897 return encoded_string;
2881 } 2898 }
2882 2899
2883 static int 2900 static int
2884 base64_encode_1 (from, to, length, line_break) 2901 base64_encode_1 (from, to, length, line_break)
2885 const char *from; 2902 const char *from;
2973 ibeg = CHAR_TO_BYTE (XFASTINT (beg)); 2990 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
2974 iend = CHAR_TO_BYTE (XFASTINT (end)); 2991 iend = CHAR_TO_BYTE (XFASTINT (end));
2975 2992
2976 length = iend - ibeg; 2993 length = iend - ibeg;
2977 /* We need to allocate enough room for decoding the text. */ 2994 /* We need to allocate enough room for decoding the text. */
2978 decoded = (char *) alloca (length); 2995 if (length <= MAX_ALLOCA)
2996 decoded = (char *) alloca (length);
2997 else
2998 decoded = (char *) xmalloc (length);
2979 2999
2980 move_gap_both (XFASTINT (beg), ibeg); 3000 move_gap_both (XFASTINT (beg), ibeg);
2981 decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length); 3001 decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length);
2982 if (decoded_length > length) 3002 if (decoded_length > length)
2983 abort (); 3003 abort ();
2994 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg); 3014 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
2995 insert_1_both (" ", 2, 2, 0, 1, 0); 3015 insert_1_both (" ", 2, 2, 0, 1, 0);
2996 TEMP_SET_PT_BOTH (XFASTINT (beg) + 1, ibeg + 1); 3016 TEMP_SET_PT_BOTH (XFASTINT (beg) + 1, ibeg + 1);
2997 insert (decoded, decoded_length); 3017 insert (decoded, decoded_length);
2998 inserted_chars = PT - (XFASTINT (beg) + 1); 3018 inserted_chars = PT - (XFASTINT (beg) + 1);
3019 if (length > MAX_ALLOCA)
3020 free (decoded);
2999 /* At first delete the original text. This never cause byte 3021 /* At first delete the original text. This never cause byte
3000 combining. */ 3022 combining. */
3001 del_range_both (PT + 1, PT_BYTE + 1, XFASTINT (end) + inserted_chars + 2, 3023 del_range_both (PT + 1, PT_BYTE + 1, XFASTINT (end) + inserted_chars + 2,
3002 iend + decoded_length + 2, 1); 3024 iend + decoded_length + 2, 1);
3003 /* Next delete the extra spaces. This will cause byte combining 3025 /* Next delete the extra spaces. This will cause byte combining
3023 (string) 3045 (string)
3024 Lisp_Object string; 3046 Lisp_Object string;
3025 { 3047 {
3026 char *decoded; 3048 char *decoded;
3027 int length, decoded_length; 3049 int length, decoded_length;
3050 Lisp_Object decoded_string;
3028 3051
3029 CHECK_STRING (string, 1); 3052 CHECK_STRING (string, 1);
3030 3053
3031 length = STRING_BYTES (XSTRING (string)); 3054 length = STRING_BYTES (XSTRING (string));
3032 /* We need to allocate enough room for decoding the text. */ 3055 /* We need to allocate enough room for decoding the text. */
3033 decoded = (char *) alloca (length); 3056 if (length <= MAX_ALLOCA)
3057 decoded = (char *) alloca (length);
3058 else
3059 decoded = (char *) xmalloc (length);
3034 3060
3035 decoded_length = base64_decode_1 (XSTRING (string)->data, decoded, length); 3061 decoded_length = base64_decode_1 (XSTRING (string)->data, decoded, length);
3036 if (decoded_length > length) 3062 if (decoded_length > length)
3037 abort (); 3063 abort ();
3038 3064
3039 if (decoded_length < 0) 3065 if (decoded_length < 0)
3040 return Qnil; 3066 return Qnil;
3041 3067
3042 return make_string (decoded, decoded_length); 3068 decoded_string = make_string (decoded, decoded_length);
3069 if (length > MAX_ALLOCA)
3070 free (decoded);
3071
3072 return decoded_string;
3043 } 3073 }
3044 3074
3045 static int 3075 static int
3046 base64_decode_1 (from, to, length) 3076 base64_decode_1 (from, to, length)
3047 const char *from; 3077 const char *from;