/[winpt]/trunk/w32gpgme/data.c
ViewVC logotype

Annotation of /trunk/w32gpgme/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 51 - (hide annotations)
Wed Nov 2 08:48:33 2005 UTC (19 years, 4 months ago) by twoaday
File MIME type: text/plain
File size: 5145 byte(s)
Fix crash caused by buggy word-wrapping code.


1 werner 36 #include <windows.h>
2     #include <malloc.h>
3     #include <string.h>
4     #include <stdio.h>
5    
6     #include "w32gpgme.h"
7    
8    
9 twoaday 51 /* Implement a word based line break. @inp is the input buffer
10     and @wraplen is the maximal line length.
11     Return value: the wrapped buffer on success. */
12     char*
13     wrap_lines (char *inp, size_t inlen, size_t wraplen, size_t *r_len)
14 werner 36 {
15 twoaday 51 char *out;
16     char *p, *inp_ptr;
17     int end_is_le=0, add_le=0;
18     size_t n;
19 werner 36
20 twoaday 51 inp[inlen] = 0;
21     if (inp[inlen-2] == '\r' && inp[inlen-1] == '\n')
22     end_is_le = 1;
23     out = calloc (1, 4*inlen/3+2+1);
24     if (!out)
25 werner 36 return NULL;
26 twoaday 51 n = 0;
27     inp_ptr = inp;
28     while ((p = strsep (&inp_ptr, " \n"))) {
29     if (strlen (p) == 0) {
30     strcat (out, " ");
31     n++;
32     continue;
33     }
34     /* if we find an existing \r\n pair, we generate a break
35     at the given position and reset the counter. */
36     if (p[strlen (p)-1] == '\r') {
37     p[strlen (p)-1]=0;
38     add_le=1;
39     }
40     else
41     add_le=0;
42     if (n + strlen (p) > wraplen) {
43     strcat (out, "\r\n");
44     n = 0;
45     }
46     else if (n > 0 || add_le) {
47     strcat (out, " ");
48     n++;
49     }
50 werner 36
51 twoaday 51 n += strlen (p);
52     strcat (out, p);
53     if (add_le) {
54     strcat (out, "\r\n");
55     n = 0;
56     }
57 werner 36 }
58 twoaday 51 if (end_is_le)
59     strcat (out, "\r\n");
60     *r_len = strlen (out);
61     return out;
62 werner 36 }
63    
64    
65     /* Wrap the lines of @r_dh with a line length of @wraplen.
66     @r_dh will be released and on success it contains the
67     handle to the wrapped data.
68     Return value: 0 on success. */
69     gpgme_error_t
70     gpg_data_wrap_lines (gpgme_data_t *r_dh, size_t wraplen)
71     {
72     gpgme_error_t err;
73     gpgme_data_t mdh;
74     char *raw = NULL;
75     char *p = NULL;
76     size_t nlen;
77    
78     err = gpgme_data_new (&mdh);
79     if (err)
80     return err;
81 twoaday 51
82 werner 36 raw = gpgme_data_release_and_get_mem (*r_dh, &nlen);
83     if (!raw) {
84 twoaday 51 gpgme_data_release (mdh);
85     return gpg_error (GPG_ERR_INV_ARG);
86 werner 36 }
87 twoaday 51
88 werner 36 p = wrap_lines (raw, nlen, wraplen, &nlen);
89 twoaday 51 if (p) {
90     gpgme_data_write (mdh, p, nlen);
91     gpgme_data_rewind (mdh);
92     free (p);
93 werner 36 }
94 twoaday 51 gpgme_free (raw);
95 werner 36 *r_dh = mdh;
96     return 0;
97     }
98    
99    
100     /* Prepend '> ' to each line into @r_dh. On success @r_dh
101     contains a handle to the quoted data.
102     Return value: 0 on success. */
103     gpgme_error_t
104     gpg_data_mail_quote (gpgme_data_t *r_dh)
105     {
106     gpgme_data_t dh;
107     char buf[128];
108    
109     if (!*r_dh)
110     return gpg_error (GPG_ERR_INV_ARG);
111     gpgme_data_new (&dh);
112     while (gpg_data_readline (*r_dh, buf, 127)) {
113     gpgme_data_write (dh, "> ", 2);
114     gpgme_data_write (dh, buf, strlen (buf));
115     }
116     gpgme_data_release (*r_dh);
117     *r_dh = dh;
118     return 0;
119     }
120    
121 twoaday 51
122 werner 36 /* Extract the plaintext data from the escaped data object @sig.
123     The plaintxt is stored in @r_plain.
124     Return value: 0 on success. */
125     gpgme_error_t
126     gpg_data_extract_plaintext (gpgme_data_t sig, gpgme_data_t *r_plain)
127     {
128     gpgme_data_t plain;
129     gpgme_error_t err;
130     char line[128+32];
131     int pos = 0;
132     int sig_begin = 0;
133    
134     if (r_plain)
135     *r_plain = NULL;
136     err = gpgme_data_new (&plain);
137     if (err)
138     return err;
139    
140     while (gpg_data_readline (sig, line, 128) > 0) {
141     if (!strncmp (line, "-----BEGIN PGP SIGNED MESSAGE", 29) ||
142     !strncmp (line, "Version:", 8) ||
143     !strncmp (line, "Comment:", 8) ||
144     !strncmp (line, "Charset:", 8) ||
145     !strncmp (line, "Hash:", 5) ||
146     !strncmp (line, "MessageID", 9))
147     continue;
148     if (strlen (line) <= 2)
149     break; /* parsed all headers, now we reached the body */
150     }
151     /* XXX handle multi dash escaped sequences */
152     while (gpg_data_readline (sig, line, 128) > 0 ) {
153     if (!strncmp( line, "-----BEGIN PGP SIGNATURE", 24))
154     break; /* end of plaintext */
155     if (!strncmp (line, "- -", 3))
156     pos = 2;
157     gpgme_data_write (plain, line+pos, strlen (line+pos));
158     pos = 0;
159     }
160     gpgme_data_write (plain, "", 1);
161     if (r_plain)
162     *r_plain = plain;
163     else
164     gpgme_data_release (plain);
165     return err;
166     }
167    
168    
169     /* Release the data in @dh and store the contents in the file @fname.
170     Return value: 0 on success. */
171     gpgme_error_t
172     gpg_data_release_and_set_file (gpgme_data_t dh, const char *fname)
173     {
174     char *p = NULL;
175     FILE *fp;
176     size_t n;
177    
178     fp = fopen (fname, "wb");
179     if (fp == NULL)
180 twoaday 51 return gpg_error (GPG_ERR_ENOENT);
181 werner 36
182     p = gpgme_data_release_and_get_mem (dh, &n);
183     if (p) {
184     fwrite (p, 1, n, fp);
185     fflush (fp);
186     memset (p, 0xFF, n);
187     gpgme_free (p);
188     }
189     fclose (fp);
190     return 0;
191     }
192    
193    
194     /* Try to read a line, terminated by \n from the given
195     gpgme data object @dh into @line.
196     Return value: numbers of chars read. */
197     size_t
198     gpg_data_readline (gpgme_data_t dh, char *line, size_t nbytes)
199     {
200     char ch = 0;
201     int nread = 0, pos = 0;
202    
203     if (!dh)
204     return 0;
205    
206     memset (line, 0, nbytes);
207     while ((nread=gpgme_data_read (dh, &ch, 1)) > 0) {
208     if (!nread)
209     break;
210     if (ch == '\n') {
211     line[pos++] = ch;
212     line[pos++] = '\0';
213     break;
214     }
215     line[pos++] = ch;
216     if (pos > (int)nbytes) {
217     line[pos++] = '\0';
218     break;
219     }
220     }
221    
222     return pos;
223     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26