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

Contents of /trunk/w32gpgme/data.c

Parent Directory Parent Directory | Revision Log Revision Log


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


1 #include <windows.h>
2 #include <malloc.h>
3 #include <string.h>
4 #include <stdio.h>
5
6 #include "w32gpgme.h"
7
8
9 /* 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 {
15 char *out;
16 char *p, *inp_ptr;
17 int end_is_le=0, add_le=0;
18 size_t n;
19
20 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 return NULL;
26 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
51 n += strlen (p);
52 strcat (out, p);
53 if (add_le) {
54 strcat (out, "\r\n");
55 n = 0;
56 }
57 }
58 if (end_is_le)
59 strcat (out, "\r\n");
60 *r_len = strlen (out);
61 return out;
62 }
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
82 raw = gpgme_data_release_and_get_mem (*r_dh, &nlen);
83 if (!raw) {
84 gpgme_data_release (mdh);
85 return gpg_error (GPG_ERR_INV_ARG);
86 }
87
88 p = wrap_lines (raw, nlen, wraplen, &nlen);
89 if (p) {
90 gpgme_data_write (mdh, p, nlen);
91 gpgme_data_rewind (mdh);
92 free (p);
93 }
94 gpgme_free (raw);
95 *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
122 /* 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 return gpg_error (GPG_ERR_ENOENT);
181
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