|
ferencd@0
|
1 //
|
|
ferencd@0
|
2 // VMime library (http://www.vmime.org)
|
|
ferencd@0
|
3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
|
ferencd@0
|
4 //
|
|
ferencd@0
|
5 // This program is free software; you can redistribute it and/or
|
|
ferencd@0
|
6 // modify it under the terms of the GNU General Public License as
|
|
ferencd@0
|
7 // published by the Free Software Foundation; either version 3 of
|
|
ferencd@0
|
8 // the License, or (at your option) any later version.
|
|
ferencd@0
|
9 //
|
|
ferencd@0
|
10 // This program is distributed in the hope that it will be useful,
|
|
ferencd@0
|
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
ferencd@0
|
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
ferencd@0
|
13 // General Public License for more details.
|
|
ferencd@0
|
14 //
|
|
ferencd@0
|
15 // You should have received a copy of the GNU General Public License along
|
|
ferencd@0
|
16 // with this program; if not, write to the Free Software Foundation, Inc.,
|
|
ferencd@0
|
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
ferencd@0
|
18 //
|
|
ferencd@0
|
19 // Linking this library statically or dynamically with other modules is making
|
|
ferencd@0
|
20 // a combined work based on this library. Thus, the terms and conditions of
|
|
ferencd@0
|
21 // the GNU General Public License cover the whole combination.
|
|
ferencd@0
|
22 //
|
|
ferencd@0
|
23
|
|
ferencd@0
|
24 #include "tests/testUtils.hpp"
|
|
ferencd@0
|
25
|
|
ferencd@0
|
26 #include <locale>
|
|
ferencd@0
|
27 #include <clocale>
|
|
ferencd@0
|
28
|
|
ferencd@0
|
29
|
|
ferencd@0
|
30 VMIME_TEST_SUITE_BEGIN(textTest)
|
|
ferencd@0
|
31
|
|
ferencd@0
|
32 VMIME_TEST_LIST_BEGIN
|
|
ferencd@0
|
33 VMIME_TEST(testConstructors)
|
|
ferencd@0
|
34 VMIME_TEST(testCopy)
|
|
ferencd@0
|
35 VMIME_TEST(testNewFromString)
|
|
ferencd@0
|
36 VMIME_TEST(testDisplayForm)
|
|
ferencd@0
|
37 VMIME_TEST(testParse)
|
|
ferencd@0
|
38 VMIME_TEST(testGenerate)
|
|
ferencd@0
|
39
|
|
ferencd@0
|
40 VMIME_TEST(testWordConstructors)
|
|
ferencd@0
|
41 VMIME_TEST(testWordParse)
|
|
ferencd@0
|
42 VMIME_TEST(testWordGenerate)
|
|
ferencd@0
|
43 VMIME_TEST(testWordGenerateSpace)
|
|
ferencd@0
|
44 VMIME_TEST(testWordGenerateSpace2)
|
|
ferencd@0
|
45 VMIME_TEST(testWordGenerateMultiBytes)
|
|
ferencd@0
|
46 VMIME_TEST(testWordGenerateQuote)
|
|
ferencd@0
|
47 VMIME_TEST(testWordGenerateSpecialCharsets)
|
|
ferencd@0
|
48 VMIME_TEST(testWordGenerateSpecials)
|
|
ferencd@0
|
49
|
|
ferencd@0
|
50 VMIME_TEST(testWhitespace)
|
|
ferencd@0
|
51 VMIME_TEST(testWhitespaceMBox)
|
|
ferencd@0
|
52
|
|
ferencd@0
|
53 VMIME_TEST(testFoldingAscii)
|
|
ferencd@0
|
54 VMIME_TEST(testForcedNonEncoding)
|
|
ferencd@0
|
55
|
|
ferencd@0
|
56 VMIME_TEST(testBugFix20110511)
|
|
ferencd@0
|
57
|
|
ferencd@0
|
58 VMIME_TEST(testInternationalizedEmail_specialChars)
|
|
ferencd@0
|
59 VMIME_TEST(testInternationalizedEmail_UTF8)
|
|
ferencd@0
|
60 VMIME_TEST(testInternationalizedEmail_nonUTF8)
|
|
ferencd@0
|
61 VMIME_TEST(testInternationalizedEmail_folding)
|
|
ferencd@0
|
62 VMIME_TEST_LIST_END
|
|
ferencd@0
|
63
|
|
ferencd@0
|
64
|
|
ferencd@0
|
65 static const vmime::string getDisplayText(const vmime::text& t)
|
|
ferencd@0
|
66 {
|
|
ferencd@0
|
67 return t.getWholeBuffer();
|
|
ferencd@0
|
68 }
|
|
ferencd@0
|
69
|
|
ferencd@0
|
70 static const vmime::string cleanGeneratedWords(const std::string& str)
|
|
ferencd@0
|
71 {
|
|
ferencd@0
|
72 std::istringstream iss(str);
|
|
ferencd@0
|
73
|
|
ferencd@0
|
74 std::string res;
|
|
ferencd@0
|
75 std::string x;
|
|
ferencd@0
|
76
|
|
ferencd@0
|
77 while (std::getline(iss, x))
|
|
ferencd@0
|
78 res += vmime::utility::stringUtils::trim(x);
|
|
ferencd@0
|
79
|
|
ferencd@0
|
80 return res;
|
|
ferencd@0
|
81 }
|
|
ferencd@0
|
82
|
|
ferencd@0
|
83
|
|
ferencd@0
|
84 void setUp()
|
|
ferencd@0
|
85 {
|
|
ferencd@0
|
86 // Set the global C and C++ locale to the user-configured locale.
|
|
ferencd@0
|
87 // The locale should use UTF-8 encoding for these tests to run successfully.
|
|
ferencd@0
|
88 try
|
|
ferencd@0
|
89 {
|
|
ferencd@0
|
90 std::locale::global(std::locale(""));
|
|
ferencd@0
|
91 }
|
|
ferencd@0
|
92 catch (std::exception &)
|
|
ferencd@0
|
93 {
|
|
ferencd@0
|
94 std::setlocale(LC_ALL, "");
|
|
ferencd@0
|
95 }
|
|
ferencd@0
|
96 }
|
|
ferencd@0
|
97
|
|
ferencd@0
|
98 void tearDown()
|
|
ferencd@0
|
99 {
|
|
ferencd@0
|
100 // Restore default locale
|
|
ferencd@0
|
101 std::locale::global(std::locale("C"));
|
|
ferencd@0
|
102 }
|
|
ferencd@0
|
103
|
|
ferencd@0
|
104
|
|
ferencd@0
|
105 void testConstructors()
|
|
ferencd@0
|
106 {
|
|
ferencd@0
|
107 vmime::text t1;
|
|
ferencd@0
|
108
|
|
ferencd@0
|
109 VASSERT_EQ("1.1", 0, t1.getWordCount());
|
|
ferencd@0
|
110
|
|
ferencd@0
|
111 vmime::text t2("Test\xa9\xc3");
|
|
ferencd@0
|
112
|
|
ferencd@0
|
113 VASSERT_EQ("2.1", 1, t2.getWordCount());
|
|
ferencd@0
|
114 VASSERT_EQ("2.2", "Test\xa9\xc3", t2.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
115 VASSERT_EQ("2.3", vmime::charset::getLocalCharset(), t2.getWordAt(0)->getCharset());
|
|
ferencd@0
|
116
|
|
ferencd@0
|
117 vmime::text t3("Test\xa9\xc3", vmime::charset(vmime::charsets::ISO8859_13));
|
|
ferencd@0
|
118
|
|
ferencd@0
|
119 VASSERT_EQ("3.1", 1, t3.getWordCount());
|
|
ferencd@0
|
120 VASSERT_EQ("3.2", "Test\xa9\xc3", t3.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
121 VASSERT_EQ("3.3", vmime::charset(vmime::charsets::ISO8859_13), t3.getWordAt(0)->getCharset());
|
|
ferencd@0
|
122
|
|
ferencd@0
|
123 vmime::word w1("Test", vmime::charset(vmime::charsets::UTF_8));
|
|
ferencd@0
|
124 vmime::text t4(w1);
|
|
ferencd@0
|
125
|
|
ferencd@0
|
126 VASSERT_EQ("4.1", 1, t4.getWordCount());
|
|
ferencd@0
|
127 VASSERT_EQ("4.2", w1.getBuffer(), t4.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
128 VASSERT_EQ("4.3", w1.getCharset(), t4.getWordAt(0)->getCharset());
|
|
ferencd@0
|
129
|
|
ferencd@0
|
130 vmime::word w2("Other", vmime::charset(vmime::charsets::US_ASCII));
|
|
ferencd@0
|
131 t4.appendWord(vmime::make_shared <vmime::word>(w2));
|
|
ferencd@0
|
132
|
|
ferencd@0
|
133 vmime::text t5(t4);
|
|
ferencd@0
|
134
|
|
ferencd@0
|
135 VASSERT_EQ("5.1", 2, t5.getWordCount());
|
|
ferencd@0
|
136 VASSERT_EQ("5.2", w1.getBuffer(), t5.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
137 VASSERT_EQ("5.3", w1.getCharset(), t5.getWordAt(0)->getCharset());
|
|
ferencd@0
|
138 VASSERT_EQ("5.4", w2.getBuffer(), t5.getWordAt(1)->getBuffer());
|
|
ferencd@0
|
139 VASSERT_EQ("5.5", w2.getCharset(), t5.getWordAt(1)->getCharset());
|
|
ferencd@0
|
140 }
|
|
ferencd@0
|
141
|
|
ferencd@0
|
142 void testCopy()
|
|
ferencd@0
|
143 {
|
|
ferencd@0
|
144 vmime::text t1("Test: \xa9\xc3");
|
|
ferencd@0
|
145
|
|
ferencd@0
|
146 VASSERT("operator==", t1 == t1);
|
|
ferencd@0
|
147 VASSERT("clone", *vmime::clone(t1) == t1);
|
|
ferencd@0
|
148
|
|
ferencd@0
|
149 vmime::text t2;
|
|
ferencd@0
|
150 t2.copyFrom(t1);
|
|
ferencd@0
|
151
|
|
ferencd@0
|
152 VASSERT("copyFrom", t1 == t2);
|
|
ferencd@0
|
153 }
|
|
ferencd@0
|
154
|
|
ferencd@0
|
155 void testNewFromString()
|
|
ferencd@0
|
156 {
|
|
ferencd@0
|
157 vmime::string s1 = "only ASCII characters";
|
|
ferencd@0
|
158 vmime::charset c1("test");
|
|
ferencd@0
|
159 vmime::text t1;
|
|
ferencd@0
|
160
|
|
ferencd@0
|
161 t1.createFromString(s1, c1);
|
|
ferencd@0
|
162
|
|
ferencd@0
|
163 VASSERT_EQ("1.1", 1, t1.getWordCount());
|
|
ferencd@0
|
164 VASSERT_EQ("1.2", s1, t1.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
165 VASSERT_EQ("1.3", vmime::charset(vmime::charsets::US_ASCII), t1.getWordAt(0)->getCharset());
|
|
ferencd@0
|
166
|
|
ferencd@0
|
167 vmime::string s2_1 = "some ASCII characters and special chars: ";
|
|
ferencd@0
|
168 vmime::string s2_2 = "\xf1\xf2\xf3\xf4 ";
|
|
ferencd@0
|
169 vmime::string s2_3 = "and then more ASCII chars.";
|
|
ferencd@0
|
170 vmime::string s2 = s2_1 + s2_2 + s2_3;
|
|
ferencd@0
|
171 vmime::charset c2("test");
|
|
ferencd@0
|
172 vmime::text t2;
|
|
ferencd@0
|
173
|
|
ferencd@0
|
174 t2.createFromString(s2, c2);
|
|
ferencd@0
|
175
|
|
ferencd@0
|
176 VASSERT_EQ("2.1", 3, t2.getWordCount());
|
|
ferencd@0
|
177 VASSERT_EQ("2.2", "some ASCII characters and special chars: ", t2.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
178 VASSERT_EQ("2.3", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(0)->getCharset());
|
|
ferencd@0
|
179 VASSERT_EQ("2.4", "\xf1\xf2\xf3\xf4", t2.getWordAt(1)->getBuffer());
|
|
ferencd@0
|
180 VASSERT_EQ("2.5", c2, t2.getWordAt(1)->getCharset());
|
|
ferencd@0
|
181 VASSERT_EQ("2.6", "and then more ASCII chars.", t2.getWordAt(2)->getBuffer());
|
|
ferencd@0
|
182 VASSERT_EQ("2.7", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(2)->getCharset());
|
|
ferencd@0
|
183 }
|
|
ferencd@0
|
184
|
|
ferencd@0
|
185 static const vmime::string parseText(const vmime::string& buffer)
|
|
ferencd@0
|
186 {
|
|
ferencd@0
|
187 vmime::text t;
|
|
ferencd@0
|
188 t.parse(buffer);
|
|
ferencd@0
|
189
|
|
ferencd@0
|
190 std::ostringstream oss;
|
|
ferencd@0
|
191 oss << t;
|
|
ferencd@0
|
192
|
|
ferencd@0
|
193 return (oss.str());
|
|
ferencd@0
|
194 }
|
|
ferencd@0
|
195
|
|
ferencd@0
|
196 void testParse()
|
|
ferencd@0
|
197 {
|
|
ferencd@0
|
198 // From RFC-2047
|
|
ferencd@0
|
199 VASSERT_EQ("1", "[text: [[word: charset=US-ASCII, buffer=Keith Moore]]]",
|
|
ferencd@0
|
200 parseText("=?US-ASCII?Q?Keith_Moore?="));
|
|
ferencd@0
|
201
|
|
ferencd@0
|
202 VASSERT_EQ("2", "[text: [[word: charset=ISO-8859-1, buffer=Keld J\xf8rn Simonsen]]]",
|
|
ferencd@0
|
203 parseText("=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?="));
|
|
ferencd@0
|
204
|
|
ferencd@0
|
205 VASSERT_EQ("3", "[text: [[word: charset=ISO-8859-1, buffer=Andr\xe9]," \
|
|
ferencd@0
|
206 "[word: charset=us-ascii, buffer= Pirard]]]",
|
|
ferencd@0
|
207 parseText("=?ISO-8859-1?Q?Andr=E9?= Pirard"));
|
|
ferencd@0
|
208
|
|
ferencd@0
|
209 VASSERT_EQ("4", "[text: [[word: charset=ISO-8859-1, buffer=If you can read this yo]," \
|
|
ferencd@0
|
210 "[word: charset=ISO-8859-2, buffer=u understand the example.]]]",
|
|
ferencd@0
|
211 parseText("=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n " \
|
|
ferencd@0
|
212 "=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?="));
|
|
ferencd@0
|
213
|
|
ferencd@0
|
214 // Bugfix: in "=?charset?q?=XX=YY?=", the "?=" finish
|
|
ferencd@0
|
215 // sequence was not correctly found (should be the one
|
|
ferencd@0
|
216 // after '=YY' and not the one after '?q').
|
|
ferencd@0
|
217 VASSERT_EQ("5", "[text: [[word: charset=abc, buffer=\xe9\xe9]]]",
|
|
ferencd@0
|
218 parseText("=?abc?q?=E9=E9?="));
|
|
ferencd@0
|
219
|
|
ferencd@0
|
220 // Question marks (?) in the middle of the string
|
|
ferencd@0
|
221 VASSERT_EQ("6", "[text: [[word: charset=iso-8859-1, buffer=Know wh\xe4t? It works!]]]",
|
|
ferencd@0
|
222 parseText("=?iso-8859-1?Q?Know_wh=E4t?_It_works!?="));
|
|
ferencd@0
|
223
|
|
ferencd@0
|
224 // With language specifier
|
|
ferencd@0
|
225 VASSERT_EQ("7", "[text: [[word: charset=US-ASCII, buffer=Keith Moore, lang=EN]]]",
|
|
ferencd@0
|
226 parseText("=?US-ASCII*EN?Q?Keith_Moore?="));
|
|
ferencd@0
|
227 }
|
|
ferencd@0
|
228
|
|
ferencd@0
|
229 void testGenerate()
|
|
ferencd@0
|
230 {
|
|
ferencd@0
|
231 // TODO
|
|
ferencd@0
|
232
|
|
ferencd@0
|
233 // With language specifier
|
|
ferencd@0
|
234 vmime::word wlang1("Émeline", vmime::charset("UTF-8"), "FR");
|
|
ferencd@0
|
235 VASSERT_EQ("lang1", "=?UTF-8*FR?Q?=C3=89meline?=", wlang1.generate());
|
|
ferencd@0
|
236
|
|
ferencd@0
|
237 vmime::word wlang2("Keith Moore", vmime::charset("US-ASCII"), "EN");
|
|
ferencd@0
|
238 VASSERT_EQ("lang2", "=?US-ASCII*EN?Q?Keith_Moore?=", wlang2.generate());
|
|
ferencd@0
|
239 }
|
|
ferencd@0
|
240
|
|
ferencd@0
|
241 void testDisplayForm()
|
|
ferencd@0
|
242 {
|
|
ferencd@0
|
243 #define DISPLAY_FORM(x) getDisplayText(*vmime::text::decodeAndUnfold(x))
|
|
ferencd@0
|
244
|
|
ferencd@0
|
245 // From RFC-2047
|
|
ferencd@0
|
246 VASSERT_EQ("1", "a", DISPLAY_FORM("=?ISO-8859-1?Q?a?="));
|
|
ferencd@0
|
247 VASSERT_EQ("2", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a?= b"));
|
|
ferencd@0
|
248 VASSERT_EQ("3", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?="));
|
|
ferencd@0
|
249 VASSERT_EQ("4", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= \t =?ISO-8859-1?Q?b?="));
|
|
ferencd@0
|
250 VASSERT_EQ("5", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= \r\n \t =?ISO-8859-1?Q?b?="));
|
|
ferencd@0
|
251 VASSERT_EQ("6", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a_b?="));
|
|
ferencd@0
|
252 VASSERT_EQ("7", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?="));
|
|
ferencd@0
|
253
|
|
ferencd@0
|
254 // Some more tests...
|
|
ferencd@0
|
255 VASSERT_EQ("8", "a b", DISPLAY_FORM(" a =?ISO-8859-1?Q?b?= "));
|
|
ferencd@0
|
256 VASSERT_EQ("9", "a b ", DISPLAY_FORM(" \t =?ISO-8859-1?Q?a?= b "));
|
|
ferencd@0
|
257 VASSERT_EQ("10", "a b", DISPLAY_FORM(" a\r\n\t b"));
|
|
ferencd@0
|
258
|
|
ferencd@0
|
259 VASSERT_EQ("11", "a b c", DISPLAY_FORM("a =?ISO-8859-1?Q?b?= c"));
|
|
ferencd@0
|
260 VASSERT_EQ("12", "a b c ", DISPLAY_FORM("a =?ISO-8859-1?Q?b?= c "));
|
|
ferencd@0
|
261 VASSERT_EQ("13", "a b c ", DISPLAY_FORM(" a =?ISO-8859-1?Q?b?= c "));
|
|
ferencd@0
|
262 VASSERT_EQ("14", "a b c d", DISPLAY_FORM("a =?ISO-8859-1?Q?b?= c =?ISO-8859-1?Q?d?= "));
|
|
ferencd@0
|
263 VASSERT_EQ("15", "a b c d e", DISPLAY_FORM("a =?ISO-8859-1?Q?b?= c =?ISO-8859-1?Q?d?= e"));
|
|
ferencd@0
|
264
|
|
ferencd@0
|
265 // Whitespaces and multiline
|
|
ferencd@0
|
266 VASSERT_EQ("16", "a b c d e", DISPLAY_FORM("=?ISO-8859-1?Q?a_b_?=c\n\t=?ISO-8859-1?Q?d_?=e"));
|
|
ferencd@0
|
267
|
|
ferencd@0
|
268 #undef DISPLAY_FORM
|
|
ferencd@0
|
269 }
|
|
ferencd@0
|
270
|
|
ferencd@0
|
271 void testWordConstructors()
|
|
ferencd@0
|
272 {
|
|
ferencd@0
|
273 VASSERT_EQ("1.1", vmime::charset::getLocalCharset(), vmime::word().getCharset());
|
|
ferencd@0
|
274 VASSERT_EQ("1.2", "", vmime::word().getBuffer());
|
|
ferencd@0
|
275
|
|
ferencd@0
|
276 VASSERT_EQ("2.1", vmime::charset::getLocalCharset(), vmime::word("foo").getCharset());
|
|
ferencd@0
|
277 VASSERT_EQ("2.2", "foo", vmime::word("foo").getBuffer());
|
|
ferencd@0
|
278
|
|
ferencd@0
|
279 VASSERT_EQ("3.1", "bar", vmime::word("foo", vmime::charset("bar")).getCharset().getName());
|
|
ferencd@0
|
280 VASSERT_EQ("3.2", "foo", vmime::word("foo", vmime::charset("bar")).getBuffer());
|
|
ferencd@0
|
281 }
|
|
ferencd@0
|
282
|
|
ferencd@0
|
283 void testWordParse()
|
|
ferencd@0
|
284 {
|
|
ferencd@0
|
285 // Simple encoded word
|
|
ferencd@0
|
286 vmime::word w1;
|
|
ferencd@0
|
287 w1.parse("=?foo?q?bar=E9 baz?=");
|
|
ferencd@0
|
288
|
|
ferencd@0
|
289 VASSERT_EQ("1.1", "foo", w1.getCharset().getName());
|
|
ferencd@0
|
290 VASSERT_EQ("1.2", "bar\xe9 baz", w1.getBuffer());
|
|
ferencd@0
|
291
|
|
ferencd@0
|
292 // Unencoded text
|
|
ferencd@0
|
293 vmime::word w2;
|
|
ferencd@0
|
294 w2.parse(" foo bar \tbaz...");
|
|
ferencd@0
|
295
|
|
ferencd@0
|
296 VASSERT_EQ("2.1", vmime::charset(vmime::charsets::US_ASCII), w2.getCharset());
|
|
ferencd@0
|
297 VASSERT_EQ("2.2", " foo bar \tbaz...", w2.getBuffer());
|
|
ferencd@0
|
298
|
|
ferencd@0
|
299 // Malformed word
|
|
ferencd@0
|
300 vmime::word w3;
|
|
ferencd@0
|
301 w3.parse("=?foo bar");
|
|
ferencd@0
|
302
|
|
ferencd@0
|
303 VASSERT_EQ("3.1", vmime::charset(vmime::charsets::US_ASCII), w3.getCharset());
|
|
ferencd@0
|
304 VASSERT_EQ("3.2", "=?foo bar", w3.getBuffer());
|
|
ferencd@0
|
305
|
|
ferencd@0
|
306 // Unknown encoding
|
|
ferencd@0
|
307 vmime::word w4;
|
|
ferencd@0
|
308 w4.parse("=?whatever?not_q_or_b?whatever?=");
|
|
ferencd@0
|
309
|
|
ferencd@0
|
310 VASSERT_EQ("4.1", vmime::charset(vmime::charsets::US_ASCII), w4.getCharset());
|
|
ferencd@0
|
311 VASSERT_EQ("4.2", "=?whatever?not_q_or_b?whatever?=", w4.getBuffer());
|
|
ferencd@0
|
312 }
|
|
ferencd@0
|
313
|
|
ferencd@0
|
314 void testWordGenerate()
|
|
ferencd@0
|
315 {
|
|
ferencd@0
|
316 VASSERT_EQ("1", "=?foo?Q?bar=E9_baz?=",
|
|
ferencd@0
|
317 vmime::word("bar\xe9 baz", vmime::charset("foo")).generate());
|
|
ferencd@0
|
318
|
|
ferencd@0
|
319 VASSERT_EQ("2", "=?foo?B?8fLz9PU=?=",
|
|
ferencd@0
|
320 vmime::word("\xf1\xf2\xf3\xf4\xf5", vmime::charset("foo")).generate());
|
|
ferencd@0
|
321 }
|
|
ferencd@0
|
322
|
|
ferencd@0
|
323 void testWordGenerateSpace()
|
|
ferencd@0
|
324 {
|
|
ferencd@0
|
325 // No white-space between an unencoded word and a encoded one
|
|
ferencd@0
|
326 VASSERT_EQ("1", "Bonjour =?utf-8?Q?Fran=C3=A7ois?=",
|
|
ferencd@0
|
327 vmime::text::newFromString("Bonjour Fran\xc3\xa7ois",
|
|
ferencd@0
|
328 vmime::charset("utf-8"))->generate());
|
|
ferencd@0
|
329
|
|
ferencd@0
|
330 // White-space between two encoded words
|
|
ferencd@0
|
331 vmime::text txt;
|
|
ferencd@0
|
332 txt.appendWord(vmime::make_shared <vmime::word>("\xc3\x89t\xc3\xa9", "utf-8"));
|
|
ferencd@0
|
333 txt.appendWord(vmime::make_shared <vmime::word>("Fran\xc3\xa7ois", "utf-8"));
|
|
ferencd@0
|
334
|
|
ferencd@0
|
335 const vmime::string decoded = "\xc3\x89t\xc3\xa9""Fran\xc3\xa7ois";
|
|
ferencd@0
|
336 const vmime::string encoded = "=?utf-8?B?w4l0w6k=?= =?utf-8?Q?Fran=C3=A7ois?=";
|
|
ferencd@0
|
337
|
|
ferencd@0
|
338 // -- test encoding
|
|
ferencd@0
|
339 VASSERT_EQ("2", encoded, txt.generate());
|
|
ferencd@0
|
340
|
|
ferencd@0
|
341 // -- ensure no space is added when decoding
|
|
ferencd@0
|
342 vmime::text txt2;
|
|
ferencd@0
|
343 txt2.parse(encoded, 0, encoded.length());
|
|
ferencd@0
|
344
|
|
ferencd@0
|
345 VASSERT_EQ("3", decoded, txt2.getWholeBuffer());
|
|
ferencd@0
|
346
|
|
ferencd@0
|
347 // -- test rencoding
|
|
ferencd@0
|
348 VASSERT_EQ("4", encoded, txt2.generate());
|
|
ferencd@0
|
349 }
|
|
ferencd@0
|
350
|
|
ferencd@0
|
351 void testWordGenerateSpace2()
|
|
ferencd@0
|
352 {
|
|
ferencd@0
|
353 // White-space between two encoded words (#2)
|
|
ferencd@0
|
354 vmime::text txt;
|
|
ferencd@0
|
355 txt.appendWord(vmime::make_shared <vmime::word>("Facture ", "utf-8"));
|
|
ferencd@0
|
356 txt.appendWord(vmime::make_shared <vmime::word>("\xc3\xa0", "utf-8"));
|
|
ferencd@0
|
357 txt.appendWord(vmime::make_shared <vmime::word>(" envoyer ", "utf-8"));
|
|
ferencd@0
|
358 txt.appendWord(vmime::make_shared <vmime::word>("\xc3\xa0", "utf-8"));
|
|
ferencd@0
|
359 txt.appendWord(vmime::make_shared <vmime::word>(" Martine", "utf-8"));
|
|
ferencd@0
|
360
|
|
ferencd@0
|
361 const vmime::string decoded = "Facture ""\xc3\xa0"" envoyer ""\xc3\xa0"" Martine";
|
|
ferencd@0
|
362 const vmime::string encoded = "Facture =?utf-8?B?w6A=?= envoyer =?utf-8?B?w6A=?= Martine";
|
|
ferencd@0
|
363
|
|
ferencd@0
|
364 // -- test encoding
|
|
ferencd@0
|
365 VASSERT_EQ("1", encoded, txt.generate());
|
|
ferencd@0
|
366
|
|
ferencd@0
|
367 // -- ensure no space is added when decoding
|
|
ferencd@0
|
368 vmime::text txt2;
|
|
ferencd@0
|
369 txt2.parse(encoded, 0, encoded.length());
|
|
ferencd@0
|
370
|
|
ferencd@0
|
371 VASSERT_EQ("2", decoded, txt2.getWholeBuffer());
|
|
ferencd@0
|
372
|
|
ferencd@0
|
373 // -- test rencoding
|
|
ferencd@0
|
374 VASSERT_EQ("3", encoded, txt2.generate());
|
|
ferencd@0
|
375 }
|
|
ferencd@0
|
376
|
|
ferencd@0
|
377 void testWordGenerateMultiBytes()
|
|
ferencd@0
|
378 {
|
|
ferencd@0
|
379 // Ensure we don't encode a non-integral number of characters
|
|
ferencd@0
|
380 VASSERT_EQ("1", "=?utf-8?Q?aaa?==?utf-8?Q?=C3=A9?==?utf-8?Q?zzz?=",
|
|
ferencd@0
|
381 cleanGeneratedWords(vmime::word("aaa\xc3\xa9zzz", vmime::charset("utf-8")).generate(16)));
|
|
ferencd@0
|
382
|
|
ferencd@0
|
383 VASSERT_EQ("2", "=?utf-8?Q?aaa=C3=A9?==?utf-8?Q?zzz?=",
|
|
ferencd@0
|
384 cleanGeneratedWords(vmime::word("aaa\xc3\xa9zzz", vmime::charset("utf-8")).generate(17)));
|
|
ferencd@0
|
385 }
|
|
ferencd@0
|
386
|
|
ferencd@0
|
387 void testWordGenerateQuote()
|
|
ferencd@0
|
388 {
|
|
ferencd@0
|
389 std::string str;
|
|
ferencd@0
|
390 vmime::utility::outputStreamStringAdapter os(str);
|
|
ferencd@0
|
391
|
|
ferencd@0
|
392 vmime::generationContext ctx;
|
|
ferencd@0
|
393 ctx.setMaxLineLength(1000);
|
|
ferencd@0
|
394
|
|
ferencd@0
|
395 // ASCII-only text is quotable
|
|
ferencd@0
|
396 str.clear();
|
|
ferencd@0
|
397 vmime::word("Quoted text").generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL);
|
|
ferencd@0
|
398 VASSERT_EQ("1", "\"Quoted text\"", cleanGeneratedWords(str));
|
|
ferencd@0
|
399
|
|
ferencd@0
|
400 // Text with CR/LF is not quotable
|
|
ferencd@0
|
401 str.clear();
|
|
ferencd@0
|
402 vmime::word("Non-quotable\ntext", "us-ascii").generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL);
|
|
ferencd@0
|
403 VASSERT_EQ("2", "=?us-ascii?Q?Non-quotable=0Atext?=", cleanGeneratedWords(str));
|
|
ferencd@0
|
404
|
|
ferencd@0
|
405 // Text with non-ASCII chars is not quotable
|
|
ferencd@0
|
406 str.clear();
|
|
ferencd@0
|
407 vmime::word("Non-quotable text \xc3\xa9").generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL);
|
|
ferencd@0
|
408 VASSERT_EQ("3", "=?UTF-8?Q?Non-quotable_text_=C3=A9?=", cleanGeneratedWords(str));
|
|
ferencd@0
|
409 }
|
|
ferencd@0
|
410
|
|
ferencd@0
|
411 void testWordGenerateSpecialCharsets()
|
|
ferencd@0
|
412 {
|
|
ferencd@0
|
413 // ISO-2022-JP only uses 7-bit chars but should be encoded in Base64
|
|
ferencd@0
|
414 VASSERT_EQ("1", "=?iso-2022-jp?B?XlskQiVRITwlPSVKJWshJiU9JVUlSCUmJSclIl5bKEI=?=",
|
|
ferencd@0
|
415 cleanGeneratedWords(vmime::word("^[$B%Q!<%=%J%k!&%=%U%H%&%'%\"^[(B",
|
|
ferencd@0
|
416 vmime::charset("iso-2022-jp")).generate(100)));
|
|
ferencd@0
|
417 }
|
|
ferencd@0
|
418
|
|
ferencd@0
|
419 void testWordGenerateSpecials()
|
|
ferencd@0
|
420 {
|
|
ferencd@0
|
421 // In RFC-2047, quotation marks (ASCII 22h) should be encoded
|
|
ferencd@0
|
422 VASSERT_EQ("1", "=?UTF-8?Q?=22=C3=9Cml=C3=A4ute=22?=",
|
|
ferencd@0
|
423 vmime::word("\x22\xC3\x9Cml\xC3\xA4ute\x22", vmime::charset("UTF-8")).generate());
|
|
ferencd@0
|
424 }
|
|
ferencd@0
|
425
|
|
ferencd@0
|
426 void testWhitespace()
|
|
ferencd@0
|
427 {
|
|
ferencd@0
|
428 // Create
|
|
ferencd@0
|
429 vmime::text text;
|
|
ferencd@0
|
430 text.createFromString("Achim Br\xc3\xa4ndt", vmime::charsets::UTF_8);
|
|
ferencd@0
|
431
|
|
ferencd@0
|
432 VASSERT_EQ("1", 2, text.getWordCount());
|
|
ferencd@0
|
433 VASSERT_EQ("2", "Achim ", text.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
434 VASSERT_EQ("3", "us-ascii", text.getWordAt(0)->getCharset());
|
|
ferencd@0
|
435 VASSERT_EQ("4", "Br\xc3\xa4ndt", text.getWordAt(1)->getBuffer());
|
|
ferencd@0
|
436 VASSERT_EQ("5", "utf-8", text.getWordAt(1)->getCharset());
|
|
ferencd@0
|
437
|
|
ferencd@0
|
438 // Generate
|
|
ferencd@0
|
439 VASSERT_EQ("6", "Achim =?utf-8?Q?Br=C3=A4ndt?=", text.generate());
|
|
ferencd@0
|
440
|
|
ferencd@0
|
441 // Parse
|
|
ferencd@0
|
442 text.parse("=?us-ascii?Q?Achim_?= =?utf-8?Q?Br=C3=A4ndt?=");
|
|
ferencd@0
|
443
|
|
ferencd@0
|
444 VASSERT_EQ("7", 2, text.getWordCount());
|
|
ferencd@0
|
445 VASSERT_EQ("8", "Achim ", text.getWordAt(0)->getBuffer());
|
|
ferencd@0
|
446 VASSERT_EQ("9", "us-ascii", text.getWordAt(0)->getCharset());
|
|
ferencd@0
|
447 VASSERT_EQ("10", "Br\xc3\xa4ndt", text.getWordAt(1)->getBuffer());
|
|
ferencd@0
|
448 VASSERT_EQ("11", "utf-8", text.getWordAt(1)->getCharset());
|
|
ferencd@0
|
449 }
|
|
ferencd@0
|
450
|
|
ferencd@0
|
451 void testWhitespaceMBox()
|
|
ferencd@0
|
452 {
|
|
ferencd@0
|
453 // Space MUST be encoded inside a word
|
|
ferencd@0
|
454 vmime::mailbox mbox(vmime::text("Achim Br\xc3\xa4ndt", vmime::charsets::UTF_8), "me@vmime.org");
|
|
ferencd@0
|
455 VASSERT_EQ("generate1", "=?us-ascii?Q?Achim_?= =?utf-8?Q?Br=C3=A4ndt?= <me@vmime.org>", mbox.generate());
|
|
ferencd@0
|
456
|
|
ferencd@0
|
457 vmime::text txt;
|
|
ferencd@0
|
458 txt.appendWord(vmime::make_shared <vmime::word>("Achim ", "us-ascii"));
|
|
ferencd@0
|
459 txt.appendWord(vmime::make_shared <vmime::word>("Br\xc3\xa4ndt", "utf-8"));
|
|
ferencd@0
|
460 mbox = vmime::mailbox(txt, "me@vmime.org");
|
|
ferencd@0
|
461 VASSERT_EQ("generate2", "=?us-ascii?Q?Achim_?= =?utf-8?Q?Br=C3=A4ndt?= <me@vmime.org>", mbox.generate());
|
|
ferencd@0
|
462
|
|
ferencd@0
|
463 mbox.parse("=?us-ascii?Q?Achim?= =?utf-8?Q?Br=C3=A4ndt?= <me@vmime.org>");
|
|
ferencd@0
|
464 VASSERT_EQ("parse.name.count", 2, mbox.getName().getWordCount());
|
|
ferencd@0
|
465 VASSERT_EQ("parse.name.word1.buffer", "Achim", mbox.getName().getWordAt(0)->getBuffer());
|
|
ferencd@0
|
466 VASSERT_EQ("parse.name.word1.charset", "us-ascii", mbox.getName().getWordAt(0)->getCharset());
|
|
ferencd@0
|
467 VASSERT_EQ("parse.name.word2.buffer", "Br\xc3\xa4ndt", mbox.getName().getWordAt(1)->getBuffer());
|
|
ferencd@0
|
468 VASSERT_EQ("parse.name.word2.charset", "utf-8", mbox.getName().getWordAt(1)->getCharset());
|
|
ferencd@0
|
469
|
|
ferencd@0
|
470 VASSERT_EQ("parse.email", "me@vmime.org", mbox.getEmail());
|
|
ferencd@0
|
471 }
|
|
ferencd@0
|
472
|
|
ferencd@0
|
473 void testFoldingAscii()
|
|
ferencd@0
|
474 {
|
|
ferencd@0
|
475 // In this test, no encoding is needed, but line should be folded anyway
|
|
ferencd@0
|
476 vmime::word w("01234567890123456789012345678901234567890123456789"
|
|
ferencd@0
|
477 "01234567890123456789012345678901234567890123456789", vmime::charset("us-ascii"));
|
|
ferencd@0
|
478
|
|
ferencd@0
|
479 VASSERT_EQ("fold.ascii",
|
|
ferencd@0
|
480 "=?us-ascii?Q?01234567890123456789012345678901234?=\r\n"
|
|
ferencd@0
|
481 " =?us-ascii?Q?5678901234567890123456789012345678?=\r\n"
|
|
ferencd@0
|
482 " =?us-ascii?Q?9012345678901234567890123456789?=", w.generate(50));
|
|
ferencd@0
|
483 }
|
|
ferencd@0
|
484
|
|
ferencd@0
|
485 void testForcedNonEncoding()
|
|
ferencd@0
|
486 {
|
|
ferencd@0
|
487 // Testing long unbreakable and unencodable header
|
|
ferencd@0
|
488 vmime::relay r;
|
|
ferencd@0
|
489 r.parse(" from User (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1]) by servername.hostname.com\n\t"
|
|
ferencd@0
|
490 "with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009 09:23:49 +0100");
|
|
ferencd@0
|
491
|
|
ferencd@0
|
492 VASSERT_EQ("received.long", "from User\r\n (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1])\r\n by servername.hostname.com with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009\r\n 09:23:49 +0100", r.generate(78));
|
|
ferencd@0
|
493 }
|
|
ferencd@0
|
494
|
|
ferencd@0
|
495 void testBugFix20110511()
|
|
ferencd@0
|
496 {
|
|
ferencd@0
|
497 /*
|
|
ferencd@0
|
498
|
|
ferencd@0
|
499 Using the latest version of vmime (0.9.1), encoding the following string: Jean
|
|
ferencd@0
|
500 Gwenaël Dutourd will result in:
|
|
ferencd@0
|
501 Jean =?utf-8?Q?Gwena=C3=ABl_?= Dutourd
|
|
ferencd@0
|
502 However, decoding this will result in Jean Gwenaël Dutourd (notice two spaces
|
|
ferencd@0
|
503 between the last 2 words). The encoder adds a _ after the second word, but
|
|
ferencd@0
|
504 since the last word is not encoded, the space between them is not ignored, and
|
|
ferencd@0
|
505 is decoded into an additional space.
|
|
ferencd@0
|
506
|
|
ferencd@0
|
507 See: http://sourceforge.net/projects/vmime/forums/forum/237357/topic/4531365
|
|
ferencd@0
|
508
|
|
ferencd@0
|
509 */
|
|
ferencd@0
|
510
|
|
ferencd@0
|
511 const std::string DECODED_TEXT = "Jean Gwenaël Dutourd";
|
|
ferencd@0
|
512 const std::string ENCODED_TEXT = "Jean =?utf-8?Q?Gwena=C3=ABl?= Dutourd";
|
|
ferencd@0
|
513
|
|
ferencd@0
|
514 // Encode
|
|
ferencd@0
|
515 VASSERT_EQ("encode", ENCODED_TEXT,
|
|
ferencd@0
|
516 vmime::text::newFromString(DECODED_TEXT, vmime::charset("utf-8"))->generate());
|
|
ferencd@0
|
517
|
|
ferencd@0
|
518 // Decode
|
|
ferencd@0
|
519 vmime::text t;
|
|
ferencd@0
|
520 t.parse(ENCODED_TEXT);
|
|
ferencd@0
|
521
|
|
ferencd@0
|
522 // -- words
|
|
ferencd@0
|
523 std::ostringstream oss; oss << t;
|
|
ferencd@0
|
524 VASSERT_EQ("decode1",
|
|
ferencd@0
|
525 "[text: [[word: charset=us-ascii, buffer=Jean ],"
|
|
ferencd@0
|
526 "[word: charset=utf-8, buffer=Gwenaël],"
|
|
ferencd@0
|
527 "[word: charset=us-ascii, buffer= Dutourd]]]", oss.str());
|
|
ferencd@0
|
528
|
|
ferencd@0
|
529 // -- getWholeBuffer
|
|
ferencd@0
|
530 VASSERT_EQ("decode2", DECODED_TEXT, t.getWholeBuffer());
|
|
ferencd@0
|
531 }
|
|
ferencd@0
|
532
|
|
ferencd@0
|
533 void testInternationalizedEmail_specialChars()
|
|
ferencd@0
|
534 {
|
|
ferencd@0
|
535 vmime::generationContext ctx(vmime::generationContext::getDefaultContext());
|
|
ferencd@0
|
536 ctx.setInternationalizedEmailSupport(true);
|
|
ferencd@0
|
537
|
|
ferencd@0
|
538 vmime::generationContext::switcher <vmime::generationContext> contextSwitcher(ctx);
|
|
ferencd@0
|
539
|
|
ferencd@0
|
540 // Special sequence/chars should still be encoded
|
|
ferencd@0
|
541 VASSERT_EQ("1", "=?us-ascii?Q?Test=3D=3Frfc2047_sequence?=",
|
|
ferencd@0
|
542 vmime::word("Test=?rfc2047 sequence", vmime::charset("us-ascii")).generate());
|
|
ferencd@0
|
543
|
|
ferencd@0
|
544 VASSERT_EQ("2", "=?us-ascii?Q?Line_One=0ALine_Two?=",
|
|
ferencd@0
|
545 vmime::word("Line One\nLine Two", vmime::charset("us-ascii")).generate());
|
|
ferencd@0
|
546 }
|
|
ferencd@0
|
547
|
|
ferencd@0
|
548 void testInternationalizedEmail_UTF8()
|
|
ferencd@0
|
549 {
|
|
ferencd@0
|
550 vmime::generationContext ctx(vmime::generationContext::getDefaultContext());
|
|
ferencd@0
|
551 ctx.setInternationalizedEmailSupport(true);
|
|
ferencd@0
|
552
|
|
ferencd@0
|
553 vmime::generationContext::switcher <vmime::generationContext> contextSwitcher(ctx);
|
|
ferencd@0
|
554
|
|
ferencd@0
|
555 // Already UTF-8 encoded text should be left as is
|
|
ferencd@0
|
556 VASSERT_EQ("1", "Achim Br\xc3\xa4ndt",
|
|
ferencd@0
|
557 vmime::word("Achim Br\xc3\xa4ndt", vmime::charset("utf-8")).generate());
|
|
ferencd@0
|
558 }
|
|
ferencd@0
|
559
|
|
ferencd@0
|
560 void testInternationalizedEmail_nonUTF8()
|
|
ferencd@0
|
561 {
|
|
ferencd@0
|
562 vmime::generationContext ctx(vmime::generationContext::getDefaultContext());
|
|
ferencd@0
|
563 ctx.setInternationalizedEmailSupport(true);
|
|
ferencd@0
|
564
|
|
ferencd@0
|
565 vmime::generationContext::switcher <vmime::generationContext> contextSwitcher(ctx);
|
|
ferencd@0
|
566
|
|
ferencd@0
|
567 // Non UTF-8 encoded text should first be converted to UTF-8
|
|
ferencd@0
|
568 VASSERT_EQ("1", "Achim Br\xc3\xa4ndt",
|
|
ferencd@0
|
569 vmime::word("Achim Br\xe4ndt", vmime::charset("iso-8859-1")).generate());
|
|
ferencd@0
|
570 }
|
|
ferencd@0
|
571
|
|
ferencd@0
|
572 void testInternationalizedEmail_folding()
|
|
ferencd@0
|
573 {
|
|
ferencd@0
|
574 vmime::generationContext ctx(vmime::generationContext::getDefaultContext());
|
|
ferencd@0
|
575 ctx.setInternationalizedEmailSupport(true);
|
|
ferencd@0
|
576
|
|
ferencd@0
|
577 vmime::generationContext::switcher <vmime::generationContext> contextSwitcher(ctx);
|
|
ferencd@0
|
578
|
|
ferencd@0
|
579 // RFC-2047 encoding must be performed, as line folding is needed
|
|
ferencd@0
|
580 vmime::word w1("01234567890123456789\xc3\xa0x012345678901234567890123456789"
|
|
ferencd@0
|
581 "01234567890123456789\xc3\xa0x012345678901234567890123456789", vmime::charset("utf-8"));
|
|
ferencd@0
|
582
|
|
ferencd@0
|
583 VASSERT_EQ("1",
|
|
ferencd@0
|
584 "=?utf-8?Q?01234567890123456789=C3=A0x01234567890?=\r\n"
|
|
ferencd@0
|
585 " =?utf-8?Q?1234567890123456789012345678901234567?=\r\n"
|
|
ferencd@0
|
586 " =?utf-8?Q?89=C3=A0x0123456789012345678901234567?=\r\n"
|
|
ferencd@0
|
587 " =?utf-8?Q?89?=", w1.generate(50));
|
|
ferencd@0
|
588
|
|
ferencd@0
|
589 // RFC-2047 encoding will not be forced, as words can be wrapped in a new line
|
|
ferencd@0
|
590 vmime::word w2("bla bla bla This is some '\xc3\xa0\xc3\xa7' UTF-8 encoded text", vmime::charset("utf-8"));
|
|
ferencd@0
|
591
|
|
ferencd@0
|
592 VASSERT_EQ("2",
|
|
ferencd@0
|
593 "bla bla bla This is\r\n"
|
|
ferencd@0
|
594 " some '\xc3\xa0\xc3\xa7' UTF-8\r\n"
|
|
ferencd@0
|
595 " encoded text", w2.generate(20));
|
|
ferencd@0
|
596 }
|
|
ferencd@0
|
597
|
|
ferencd@0
|
598 VMIME_TEST_SUITE_END
|
|
ferencd@0
|
599
|