Merged in outlook_mime_support branch
authorKrista Grothoff <krista@pep-project.org>
Fri, 09 Sep 2016 13:07:59 +0200
changeset 1153eaf7b2eeea87
parent 1142 b0b208f85c88
parent 1151 4b926eb03026
child 1164 51db748bdf16
child 1174 1069203104ea
child 1175 bc3d2a53ee85
child 1211 036b60be33bb
Merged in outlook_mime_support branch
     1.1 --- a/src/mime.c	Mon Sep 05 20:22:21 2016 +0200
     1.2 +++ b/src/mime.c	Fri Sep 09 13:07:59 2016 +0200
     1.3 @@ -40,112 +40,40 @@
     1.4  #define PATH_SEP '/'
     1.5  #endif
     1.6  
     1.7 +// This function was rewritten to use in-memory buffers instead of
     1.8 +// temporary files when the pgp/mime support was implemented for
     1.9 +// outlook, as the existing code did not work well on windows.
    1.10 +
    1.11  static PEP_STATUS render_mime(struct mailmime *mime, char **mimetext)
    1.12  {
    1.13      PEP_STATUS status = PEP_STATUS_OK;
    1.14 -    int fd = -1;
    1.15 -    FILE *file = NULL;
    1.16 -    size_t size;
    1.17 -    char *buf = NULL;
    1.18      int col;
    1.19      int r;
    1.20 +	size_t len;
    1.21 +	char* buf = NULL;
    1.22  
    1.23 -    char *template = NULL;
    1.24 -    char *env_tmp = getenv("TEMP");
    1.25 +	MMAPString* buffer;
    1.26  
    1.27 -    if(env_tmp){
    1.28 -        unsigned long tmp_l = strlen(env_tmp);
    1.29 -        if(tmp_l == 0 ) {
    1.30 -            goto err_file;
    1.31 -        } else {
    1.32 -            int need_sep = (env_tmp[tmp_l-1] != PATH_SEP);
    1.33 -            template = calloc(1, tmp_l + 
    1.34 -                                 (need_sep ? 1 : 0) +
    1.35 -                                 sizeof(TMP_TEMPLATE));
    1.36 -            if (template == NULL)
    1.37 -                goto enomem;
    1.38 +	buffer = mmap_string_new(NULL);
    1.39 +	if (buffer == NULL)
    1.40 +		goto enomem;
    1.41 +	
    1.42 +	col = 0;
    1.43 +	r = mailmime_write_mem(buffer, &col, mime);
    1.44 +	assert(r == MAILIMF_NO_ERROR);
    1.45 +	if (r == MAILIMF_ERROR_MEMORY)
    1.46 +		goto enomem;
    1.47 +	else if (r != MAILIMF_NO_ERROR)
    1.48 +		goto err_file;
    1.49  
    1.50 -            memcpy(template, env_tmp, tmp_l);
    1.51 -            if(need_sep)
    1.52 -                template[tmp_l] = PATH_SEP;
    1.53 -            memcpy(template + tmp_l + (need_sep ? 1 : 0), TMP_TEMPLATE, sizeof(TMP_TEMPLATE));
    1.54 -        }
    1.55 -    }else{
    1.56 -        template = strdup("/tmp/" TMP_TEMPLATE);
    1.57 -        if (template == NULL)
    1.58 -            goto enomem;
    1.59 -    }
    1.60 -    assert(template);
    1.61 +	// we overallocate by 1 byte, so we have a terminating 0.
    1.62 +	len = buffer->len;
    1.63 +	buf = calloc(len + 1, 1);
    1.64 +	if (buf == NULL)
    1.65 +		goto enomem;
    1.66  
    1.67 -    *mimetext = NULL;
    1.68 -
    1.69 -    fd = Mkstemp(template);
    1.70 -    assert(fd != -1);
    1.71 -    if (fd == -1)
    1.72 -        goto err_file;
    1.73 -
    1.74 -    r = unlink(template);
    1.75 -    assert(r == 0);
    1.76 -    if (r)
    1.77 -        goto err_file;
    1.78 -
    1.79 -    free(template);
    1.80 -    template = NULL;
    1.81 -
    1.82 -    file = Fdopen(fd, "w+");
    1.83 -    assert(file);
    1.84 -    if (file == NULL) {
    1.85 -        switch (errno) {
    1.86 -            case ENOMEM:
    1.87 -                goto enomem;
    1.88 -            default:
    1.89 -                goto err_file;
    1.90 -        }
    1.91 -    }
    1.92 -
    1.93 -    fd = -1;
    1.94 -
    1.95 -    col = 0;
    1.96 -    r = mailmime_write_file(file, &col, mime);
    1.97 -    assert(r == MAILIMF_NO_ERROR);
    1.98 -    if (r == MAILIMF_ERROR_MEMORY)
    1.99 -        goto enomem;
   1.100 -    else if (r != MAILIMF_NO_ERROR)
   1.101 -        goto err_file;
   1.102 -
   1.103 -    off_t len = ftello(file);
   1.104 -    assert(len != -1);
   1.105 -    if (len == -1 && errno == EOVERFLOW)
   1.106 -        goto err_file;
   1.107 -
   1.108 -    if (len + 1 > SIZE_MAX)
   1.109 -        goto err_buffer;
   1.110 -
   1.111 -    size = (size_t) len;
   1.112 -
   1.113 -    errno = 0;
   1.114 -    rewind(file);
   1.115 -    assert(errno == 0);
   1.116 -    switch (errno) {
   1.117 -        case 0:
   1.118 -            break;
   1.119 -        case ENOMEM:
   1.120 -            goto enomem;
   1.121 -        default:
   1.122 -            goto err_file;
   1.123 -    }
   1.124 -
   1.125 -    buf = calloc(1, size + 1);
   1.126 -    assert(buf);
   1.127 -    if (buf == NULL)
   1.128 -        goto enomem;
   1.129 - 
   1.130 -    size_t _read;
   1.131 -    _read = Fread(buf, size, 1, file);
   1.132 -    assert(_read == size);
   1.133 -
   1.134 -    r = Fclose(file);
   1.135 -    assert(r == 0);
   1.136 +	memcpy(buf, buffer->str, len);
   1.137 +	mmap_string_free(buffer);
   1.138  
   1.139      *mimetext = buf;
   1.140      return PEP_STATUS_OK;
   1.141 @@ -162,18 +90,10 @@
   1.142      status = PEP_OUT_OF_MEMORY;
   1.143  
   1.144  pep_error:
   1.145 -    free(buf);
   1.146 -    free(template);
   1.147 -
   1.148 -    if (file) {
   1.149 -        r = Fclose(file);
   1.150 -        assert(r == 0);
   1.151 -    }
   1.152 -    else if (fd != -1) {
   1.153 -        r = Close(fd);
   1.154 -        assert(r == 0);
   1.155 -    }
   1.156 -
   1.157 +	if (buffer)
   1.158 +		mmap_string_free(buffer);
   1.159 +	if (buf)
   1.160 +		free(buf);
   1.161      return status;
   1.162  }
   1.163  
   1.164 @@ -259,7 +179,11 @@
   1.165  
   1.166      *result = NULL;
   1.167  
   1.168 -    if (blob->mime_type == NULL)
   1.169 +// TODO: It seems the pep com server adapter sends an empty string here,
   1.170 +// which leads to a crash later. Thus, we workaround here by treating an
   1.171 +// empty string as NULL. We need to check whether the bug really is here,
   1.172 +// or the pep com server adapter needs to be changed.
   1.173 +    if (blob->mime_type == NULL || blob->mime_type[0] == '\0')
   1.174          mime_type = "application/octet-stream";
   1.175      else
   1.176          mime_type = blob->mime_type;