annotate 3rdparty/vmime/tests/parser/parameterTest.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
rev   line source
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(parameterTest)
ferencd@0 31
ferencd@0 32 VMIME_TEST_LIST_BEGIN
ferencd@0 33 VMIME_TEST(testParse)
ferencd@0 34 VMIME_TEST(testParseRFC2231)
ferencd@0 35 VMIME_TEST(testGenerate)
ferencd@0 36 VMIME_TEST(testGenerateRFC2231)
ferencd@0 37 VMIME_TEST(testNonStandardEncodedParam)
ferencd@0 38 VMIME_TEST(testParseNonSignificantWS)
ferencd@0 39 VMIME_TEST(testEncodeTSpecials)
ferencd@0 40 VMIME_TEST(testEncodeTSpecialsInRFC2231)
ferencd@0 41 VMIME_TEST(testWhitespaceBreaksTheValue)
ferencd@0 42 VMIME_TEST_LIST_END
ferencd@0 43
ferencd@0 44
ferencd@0 45 // HACK: parameterizedHeaderField constructor is private
ferencd@0 46 class parameterizedHeaderField : public vmime::parameterizedHeaderField
ferencd@0 47 {
ferencd@0 48 public:
ferencd@0 49
ferencd@0 50 parameterizedHeaderField()
ferencd@0 51 {
ferencd@0 52 setName("F");
ferencd@0 53 setValue(vmime::headerFieldFactory::getInstance()->createValue(getName()));
ferencd@0 54 setValue(vmime::word("X"));
ferencd@0 55 }
ferencd@0 56
ferencd@0 57 using vmime::parameterizedHeaderField::generate;
ferencd@0 58
ferencd@0 59 const vmime::string generate
ferencd@0 60 (const vmime::generationContext::EncodedParameterValueModes genMode,
ferencd@0 61 const vmime::size_t maxLineLength = 0) const
ferencd@0 62 {
ferencd@0 63 vmime::generationContext ctx(vmime::generationContext::getDefaultContext());
ferencd@0 64 ctx.setEncodedParameterValueMode(genMode);
ferencd@0 65
ferencd@0 66 if (maxLineLength != 0)
ferencd@0 67 ctx.setMaxLineLength(maxLineLength);
ferencd@0 68
ferencd@0 69 std::ostringstream oss;
ferencd@0 70 vmime::utility::outputStreamAdapter adapter(oss);
ferencd@0 71
ferencd@0 72 vmime::parameterizedHeaderField::generate(ctx, adapter);
ferencd@0 73
ferencd@0 74 return oss.str();
ferencd@0 75 }
ferencd@0 76 };
ferencd@0 77
ferencd@0 78
ferencd@0 79 #define FIELD_VALUE(f) (f.getValue()->generate())
ferencd@0 80 #define PARAM_VALUE(p, n) (p.getParameterAt(n)->getValue().generate())
ferencd@0 81 #define PARAM_NAME(p, n) (p.getParameterAt(n)->getName())
ferencd@0 82 #define PARAM_CHARSET(p, n) \
ferencd@0 83 (p.getParameterAt(n)->getValue().getCharset().generate())
ferencd@0 84 #define PARAM_LANG(p, n) \
ferencd@0 85 (p.getParameterAt(n)->getValue().getLanguage())
ferencd@0 86 #define PARAM_BUFFER(p, n) \
ferencd@0 87 (p.getParameterAt(n)->getValue().getBuffer())
ferencd@0 88
ferencd@0 89
ferencd@0 90 void setUp()
ferencd@0 91 {
ferencd@0 92 // Set the global C and C++ locale to the user-configured locale.
ferencd@0 93 // The locale should use UTF-8 encoding for these tests to run successfully.
ferencd@0 94 try
ferencd@0 95 {
ferencd@0 96 std::locale::global(std::locale(""));
ferencd@0 97 }
ferencd@0 98 catch (std::exception &)
ferencd@0 99 {
ferencd@0 100 std::setlocale(LC_ALL, "");
ferencd@0 101 }
ferencd@0 102 }
ferencd@0 103
ferencd@0 104 void tearDown()
ferencd@0 105 {
ferencd@0 106 // Restore default locale
ferencd@0 107 std::locale::global(std::locale("C"));
ferencd@0 108 }
ferencd@0 109
ferencd@0 110
ferencd@0 111 void testParse()
ferencd@0 112 {
ferencd@0 113 // Simple parameter
ferencd@0 114 parameterizedHeaderField p1;
ferencd@0 115 p1.parse("X; param1=value1;\r\n");
ferencd@0 116
ferencd@0 117 VASSERT_EQ("1.1", 1, p1.getParameterCount());
ferencd@0 118 VASSERT_EQ("1.2", "param1", PARAM_NAME(p1, 0));
ferencd@0 119 VASSERT_EQ("1.3", "value1", PARAM_VALUE(p1, 0));
ferencd@0 120
ferencd@0 121 // Multi-section parameters (1/2)
ferencd@0 122 parameterizedHeaderField p2a;
ferencd@0 123 p2a.parse("X; param1=value1;\r\n"
ferencd@0 124 " param2*0=\"val\";\r\n"
ferencd@0 125 " param2*1=\"ue2\";");
ferencd@0 126
ferencd@0 127 VASSERT_EQ("2a.1", 2, p2a.getParameterCount());
ferencd@0 128 VASSERT_EQ("2a.2", "param1", PARAM_NAME(p2a, 0));
ferencd@0 129 VASSERT_EQ("2a.3", "value1", PARAM_VALUE(p2a, 0));
ferencd@0 130 VASSERT_EQ("2a.4", "param2", PARAM_NAME(p2a, 1));
ferencd@0 131 VASSERT_EQ("2a.5", "value2", PARAM_VALUE(p2a, 1));
ferencd@0 132
ferencd@0 133 // Multi-section parameters (2/2)
ferencd@0 134 parameterizedHeaderField p2b;
ferencd@0 135 p2b.parse("X; param1=value1;\r\n"
ferencd@0 136 " param2=\"should be ignored\";\r\n"
ferencd@0 137 " param2*0=\"val\";\r\n"
ferencd@0 138 " param2*1=\"ue2\";");
ferencd@0 139
ferencd@0 140 VASSERT_EQ("2b.1", 2, p2b.getParameterCount());
ferencd@0 141 VASSERT_EQ("2b.2", "param1", PARAM_NAME(p2b, 0));
ferencd@0 142 VASSERT_EQ("2b.3", "value1", PARAM_VALUE(p2b, 0));
ferencd@0 143 VASSERT_EQ("2b.4", "param2", PARAM_NAME(p2b, 1));
ferencd@0 144 VASSERT_EQ("2b.5", "value2", PARAM_VALUE(p2b, 1));
ferencd@0 145
ferencd@0 146 // Extended parameter (charset and language information)
ferencd@0 147 parameterizedHeaderField p3;
ferencd@0 148 p3.parse("X; param1*=charset'language'value1;\r\n");
ferencd@0 149
ferencd@0 150 VASSERT_EQ("3.1", 1, p3.getParameterCount());
ferencd@0 151 VASSERT_EQ("3.2", "param1", PARAM_NAME(p3, 0));
ferencd@0 152 VASSERT_EQ("3.3", "charset", PARAM_CHARSET(p3, 0));
ferencd@0 153 VASSERT_EQ("3.4", "value1", PARAM_BUFFER(p3, 0));
ferencd@0 154
ferencd@0 155 // Encoded characters in extended parameter values
ferencd@0 156 parameterizedHeaderField p4;
ferencd@0 157 p4.parse("X; param1*=a%20value%20with%20multiple%20word%73"); // 0x73 = 's'
ferencd@0 158
ferencd@0 159 VASSERT_EQ("4.1", 1, p4.getParameterCount());
ferencd@0 160 VASSERT_EQ("4.2", "param1", PARAM_NAME(p4, 0));
ferencd@0 161 VASSERT_EQ("4.3", "a value with multiple words", PARAM_VALUE(p4, 0));
ferencd@0 162
ferencd@0 163 // Invalid encoded character
ferencd@0 164 parameterizedHeaderField p5;
ferencd@0 165 p5.parse("X; param1*=test%20value%");
ferencd@0 166
ferencd@0 167 VASSERT_EQ("5.1", 1, p5.getParameterCount());
ferencd@0 168 VASSERT_EQ("5.2", "param1", PARAM_NAME(p5, 0));
ferencd@0 169 VASSERT_EQ("5.3", "test value%", PARAM_VALUE(p5, 0));
ferencd@0 170
ferencd@0 171 // Spaces before and after '='
ferencd@0 172 parameterizedHeaderField p6;
ferencd@0 173 p6.parse("X; param1\t= \"value1\"");
ferencd@0 174
ferencd@0 175 VASSERT_EQ("6.1", 1, p6.getParameterCount());
ferencd@0 176 VASSERT_EQ("6.2", "param1", PARAM_NAME(p6, 0));
ferencd@0 177 VASSERT_EQ("6.3", "value1", PARAM_VALUE(p6, 0));
ferencd@0 178
ferencd@0 179 // Quoted strings and escaped chars
ferencd@0 180 parameterizedHeaderField p7;
ferencd@0 181 p7.parse("X; param1=\"this is a slash: \\\"\\\\\\\"\""); // \"\\\"
ferencd@0 182
ferencd@0 183 VASSERT_EQ("7.1", 1, p7.getParameterCount());
ferencd@0 184 VASSERT_EQ("7.2", "param1", PARAM_NAME(p7, 0));
ferencd@0 185 VASSERT_EQ("7.3", "this is a slash: \"\\\"", PARAM_VALUE(p7, 0));
ferencd@0 186 }
ferencd@0 187
ferencd@0 188 void testParseRFC2231()
ferencd@0 189 {
ferencd@0 190 // Extended parameter with charset specified in more than one
ferencd@0 191 // section (this is forbidden by RFC, but is should not fail)
ferencd@0 192 parameterizedHeaderField p1;
ferencd@0 193 p1.parse("X; param1*0*=charset1'language1'value1;\r\n"
ferencd@0 194 " param1*1*=charset2'language2'value2;");
ferencd@0 195
ferencd@0 196 VASSERT_EQ("1.1", 1, p1.getParameterCount());
ferencd@0 197 VASSERT_EQ("1.2", "param1", PARAM_NAME(p1, 0));
ferencd@0 198 VASSERT_EQ("1.3", "charset1", PARAM_CHARSET(p1, 0));
ferencd@0 199 VASSERT_EQ("1.4", "value1charset2'language2'value2", PARAM_BUFFER(p1, 0));
ferencd@0 200
ferencd@0 201 // Charset not specified in the first section (that is not encoded),
ferencd@0 202 // but specified in the second one (legal)
ferencd@0 203 parameterizedHeaderField p2;
ferencd@0 204 p2.parse("X; param1*0=value1;\r\n"
ferencd@0 205 " param1*1*=charset'language'value2;");
ferencd@0 206
ferencd@0 207 VASSERT_EQ("2.1", 1, p2.getParameterCount());
ferencd@0 208 VASSERT_EQ("2.2", "param1", PARAM_NAME(p2, 0));
ferencd@0 209 VASSERT_EQ("2.3", "charset", PARAM_CHARSET(p2, 0));
ferencd@0 210 VASSERT_EQ("2.4", "value1value2", PARAM_BUFFER(p2, 0));
ferencd@0 211
ferencd@0 212 // Characters prefixed with '%' in a simple (not extended) section
ferencd@0 213 // should not be decoded
ferencd@0 214 parameterizedHeaderField p3;
ferencd@0 215 p3.parse("X; param1=val%20ue1");
ferencd@0 216
ferencd@0 217 VASSERT_EQ("3.1", 1, p3.getParameterCount());
ferencd@0 218 VASSERT_EQ("3.2", "param1", PARAM_NAME(p3, 0));
ferencd@0 219 VASSERT_EQ("3.3", "val%20ue1", PARAM_VALUE(p3, 0));
ferencd@0 220
ferencd@0 221 // Multiple sections + charset specified and encoding
ferencd@0 222 parameterizedHeaderField p4;
ferencd@0 223 p4.parse("X; param1*0*=charset'language'value1a%20;"
ferencd@0 224 " param1*1*=value1b%20;"
ferencd@0 225 " param1*2=value1c");
ferencd@0 226
ferencd@0 227 VASSERT_EQ("4.1", 1, p4.getParameterCount());
ferencd@0 228 VASSERT_EQ("4.2", "param1", PARAM_NAME(p4, 0));
ferencd@0 229 VASSERT_EQ("4.3", "charset", PARAM_CHARSET(p4, 0));
ferencd@0 230 VASSERT_EQ("4.4", "value1a value1b value1c", PARAM_BUFFER(p4, 0));
ferencd@0 231
ferencd@0 232 // No charset specified: defaults to US-ASCII
ferencd@0 233 parameterizedHeaderField p5;
ferencd@0 234 p5.parse("X; param1*='language'value1");
ferencd@0 235
ferencd@0 236 VASSERT_EQ("5.1", 1, p5.getParameterCount());
ferencd@0 237 VASSERT_EQ("5.2", "param1", PARAM_NAME(p5, 0));
ferencd@0 238 VASSERT_EQ("5.3", "us-ascii", PARAM_CHARSET(p5, 0));
ferencd@0 239 VASSERT_EQ("5.4", "value1", PARAM_BUFFER(p5, 0));
ferencd@0 240
ferencd@0 241 // Language specification
ferencd@0 242 parameterizedHeaderField p6;
ferencd@0 243 p6.parse("X; param1*=us-ascii'en-us'This%20is%20%2A%2A%2Afun%2A%2A%2A");
ferencd@0 244
ferencd@0 245 VASSERT_EQ("6.1", 1, p6.getParameterCount());
ferencd@0 246 VASSERT_EQ("6.2", "param1", PARAM_NAME(p6, 0));
ferencd@0 247 VASSERT_EQ("6.3", "us-ascii", PARAM_CHARSET(p6, 0));
ferencd@0 248 VASSERT_EQ("6.4", "en-us", PARAM_LANG(p6, 0));
ferencd@0 249 VASSERT_EQ("6.5", "This is ***fun***", PARAM_BUFFER(p6, 0));
ferencd@0 250 }
ferencd@0 251
ferencd@0 252 void testGenerate()
ferencd@0 253 {
ferencd@0 254 // Simple parameter/value
ferencd@0 255 parameterizedHeaderField p1;
ferencd@0 256 p1.appendParameter(vmime::make_shared <vmime::parameter>("param1", "value1"));
ferencd@0 257
ferencd@0 258 VASSERT_EQ("1", "F: X; param1=value1", p1.generate());
ferencd@0 259
ferencd@0 260 // Value that needs quoting (1/2)
ferencd@0 261 parameterizedHeaderField p2a;
ferencd@0 262 p2a.appendParameter(vmime::make_shared <vmime::parameter>("param1", "value1a;value1b"));
ferencd@0 263
ferencd@0 264 VASSERT_EQ("2a", "F: X; param1=\"value1a;value1b\"", p2a.generate());
ferencd@0 265
ferencd@0 266 // Value that needs quoting (2/2)
ferencd@0 267 parameterizedHeaderField p2b;
ferencd@0 268 p2b.appendParameter(vmime::make_shared <vmime::parameter>("param1", "va\\lue\"1"));
ferencd@0 269
ferencd@0 270 VASSERT_EQ("2b", "F: X; param1=\"va\\\\lue\\\"1\"", p2b.generate());
ferencd@0 271 }
ferencd@0 272
ferencd@0 273 void testGenerateRFC2231()
ferencd@0 274 {
ferencd@0 275 // Extended parameter with charset specifier
ferencd@0 276 parameterizedHeaderField p1;
ferencd@0 277 p1.appendParameter(vmime::make_shared <vmime::parameter>("param1",
ferencd@0 278 vmime::word("value 1\xe9", vmime::charset("charset"))));
ferencd@0 279
ferencd@0 280 VASSERT_EQ("1.no-encoding", "F: X; param1=\"value 1\"",
ferencd@0 281 p1.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING));
ferencd@0 282
ferencd@0 283 VASSERT_EQ("1.rfc2047", "F: X; param1=\"=?charset?Q?value_1=E9?=\"",
ferencd@0 284 p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY));
ferencd@0 285
ferencd@0 286 VASSERT_EQ("1.rfc2231", "F: X; param1*=charset''value%201%E9",
ferencd@0 287 p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY));
ferencd@0 288
ferencd@0 289 VASSERT_EQ("1.both", "F: X; param1=\"=?charset?Q?value_1=E9?=\";param1*=charset''value%201%E9",
ferencd@0 290 p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047));
ferencd@0 291
ferencd@0 292 // Value that spans on multiple lines
ferencd@0 293 parameterizedHeaderField p2;
ferencd@0 294 p2.appendParameter(vmime::make_shared <vmime::parameter>("param1",
ferencd@0 295 vmime::word("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
ferencd@0 296 vmime::charset("charset"))));
ferencd@0 297
ferencd@0 298 VASSERT_EQ("2.no-encoding", "F: X; \r\n "
ferencd@0 299 "param1=abcdefghijkl",
ferencd@0 300 p2.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING, 25)); // max line length = 25
ferencd@0 301
ferencd@0 302 VASSERT_EQ("2.rfc2047", "F: X; \r\n "
ferencd@0 303 "param1=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
ferencd@0 304 p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY, 25)); // max line length = 25
ferencd@0 305
ferencd@0 306 VASSERT_EQ("2.rfc2231", "F: X; \r\n "
ferencd@0 307 "param1*0*=charset''abc;\r\n "
ferencd@0 308 "param1*1*=defghijkl;\r\n "
ferencd@0 309 "param1*2*=mnopqrstu;\r\n "
ferencd@0 310 "param1*3*=vwxyzABCD;\r\n "
ferencd@0 311 "param1*4*=EFGHIJKLM;\r\n "
ferencd@0 312 "param1*5*=NOPQRSTUV;\r\n "
ferencd@0 313 "param1*6*=WXYZ",
ferencd@0 314 p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY, 25)); // max line length = 25
ferencd@0 315
ferencd@0 316 VASSERT_EQ("2.both", "F: X; \r\n "
ferencd@0 317 "param1=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ;\r\n "
ferencd@0 318 "param1*0*=charset''abc;\r\n "
ferencd@0 319 "param1*1*=defghijkl;\r\n "
ferencd@0 320 "param1*2*=mnopqrstu;\r\n "
ferencd@0 321 "param1*3*=vwxyzABCD;\r\n "
ferencd@0 322 "param1*4*=EFGHIJKLM;\r\n "
ferencd@0 323 "param1*5*=NOPQRSTUV;\r\n "
ferencd@0 324 "param1*6*=WXYZ",
ferencd@0 325 p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047, 25)); // max line length = 25
ferencd@0 326
ferencd@0 327 // Non-ASCII parameter value
ferencd@0 328 parameterizedHeaderField p3;
ferencd@0 329 p3.appendParameter(vmime::make_shared <vmime::parameter>("param1",
ferencd@0 330 vmime::word("δσσσσσσσσσσσσσσσσσσσσδσδα δσαδσδσαδσαδασδασ δσαδασδσα δσαδασδσα δασδασδασ δασαχφδδσα 2008.doc",
ferencd@0 331 vmime::charset("utf-8"))));
ferencd@0 332
ferencd@0 333 VASSERT_EQ("3.no-encoding", "F: X; \r\n "
ferencd@0 334 "param1=\" 2008.doc\"",
ferencd@0 335 p3.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING, 80)); // max line length = 80
ferencd@0 336
ferencd@0 337 VASSERT_EQ("3.7bit-only", "F: X; \r\n "
ferencd@0 338 "param1=\"=?utf-8?B?zrTPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+DzrTPg860?=\r\n "
ferencd@0 339 "=?utf-8?B?zrEgzrTPg86xzrTPg860z4POsc60z4POsc60zrHPg860zrHPgyDOtM+DzrHOtM6x?=\r\n "
ferencd@0 340 "=?utf-8?B?z4POtM+DzrEgzrTPg86xzrTOsc+DzrTPg86xIM60zrHPg860zrHPg860zrHPgyDOtA==?=\r\n "
ferencd@0 341 "=?utf-8?B?zrHPg86xz4fPhs60zrTPg86xIDIwMDguZG9j?=\"",
ferencd@0 342 p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY, 80)); // max line length = 80
ferencd@0 343
ferencd@0 344 VASSERT_EQ("3.both", "F: X; \r\n "
ferencd@0 345 "param1=\"=?utf-8?B?zrTPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+DzrTPg860?=\r\n "
ferencd@0 346 "=?utf-8?B?zrEgzrTPg86xzrTPg860z4POsc60z4POsc60zrHPg860zrHPgyDOtM+DzrHOtM6x?=\r\n "
ferencd@0 347 "=?utf-8?B?z4POtM+DzrEgzrTPg86xzrTOsc+DzrTPg86xIM60zrHPg860zrHPg860zrHPgyDOtA==?=\r\n "
ferencd@0 348 "=?utf-8?B?zrHPg86xz4fPhs60zrTPg86xIDIwMDguZG9j?=\";\r\n "
ferencd@0 349 "param1*0*=utf-8''%CE%B4%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83;\r\n "
ferencd@0 350 "param1*1*=%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83;\r\n "
ferencd@0 351 "param1*2*=%CE%B4%CF%83%CE%B4%CE%B1%20%CE%B4%CF%83%CE%B1%CE%B4%CF%83%CE%B4%CF;\r\n "
ferencd@0 352 "param1*3*=%83%CE%B1%CE%B4%CF%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CE%B1%CF%83%20;\r\n "
ferencd@0 353 "param1*4*=%CE%B4%CF%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CF%83%CE%B1%20%CE%B4%CF;\r\n "
ferencd@0 354 "param1*5*=%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CF%83%CE%B1%20%CE%B4%CE%B1%CF%83;\r\n "
ferencd@0 355 "param1*6*=%CE%B4%CE%B1%CF%83%CE%B4%CE%B1%CF%83%20%CE%B4%CE%B1%CF%83%CE%B1%CF;\r\n "
ferencd@0 356 "param1*7*=%87%CF%86%CE%B4%CE%B4%CF%83%CE%B1%202008.doc",
ferencd@0 357 p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047, 80)); // max line length = 80
ferencd@0 358
ferencd@0 359 VASSERT_EQ("3.either", "F: X; param1*0*=utf-8''%CE%B4%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83;\r\n "
ferencd@0 360 "param1*1*=%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83;\r\n "
ferencd@0 361 "param1*2*=%CE%B4%CF%83%CE%B4%CE%B1%20%CE%B4%CF%83%CE%B1%CE%B4%CF%83%CE%B4%CF;\r\n "
ferencd@0 362 "param1*3*=%83%CE%B1%CE%B4%CF%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CE%B1%CF%83%20;\r\n "
ferencd@0 363 "param1*4*=%CE%B4%CF%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CF%83%CE%B1%20%CE%B4%CF;\r\n "
ferencd@0 364 "param1*5*=%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CF%83%CE%B1%20%CE%B4%CE%B1%CF%83;\r\n "
ferencd@0 365 "param1*6*=%CE%B4%CE%B1%CF%83%CE%B4%CE%B1%CF%83%20%CE%B4%CE%B1%CF%83%CE%B1%CF;\r\n "
ferencd@0 366 "param1*7*=%87%CF%86%CE%B4%CE%B4%CF%83%CE%B1%202008.doc",
ferencd@0 367 p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY, 80)); // max line length = 80
ferencd@0 368
ferencd@0 369 // No encoding needed
ferencd@0 370 parameterizedHeaderField p4;
ferencd@0 371 p4.appendParameter(vmime::make_shared <vmime::parameter>("param1",
ferencd@0 372 vmime::word("va lue", vmime::charset("charset"))));
ferencd@0 373
ferencd@0 374 VASSERT_EQ("4.no-encoding", "F: X; param1=\"va lue\"",
ferencd@0 375 p4.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING));
ferencd@0 376
ferencd@0 377 VASSERT_EQ("4.rfc2047", "F: X; param1=\"va lue\"",
ferencd@0 378 p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY));
ferencd@0 379
ferencd@0 380 VASSERT_EQ("4.rfc2231", "F: X; param1=\"va lue\"",
ferencd@0 381 p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY));
ferencd@0 382
ferencd@0 383 VASSERT_EQ("4.both", "F: X; param1=\"va lue\"",
ferencd@0 384 p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047));
ferencd@0 385
ferencd@0 386 // Language specification
ferencd@0 387 parameterizedHeaderField p5;
ferencd@0 388 p5.appendParameter(vmime::make_shared <vmime::parameter>("param1",
ferencd@0 389 vmime::word("This is ***fun***", vmime::charset("us-ascii"), "en-us")));
ferencd@0 390
ferencd@0 391 VASSERT_EQ("5.no-encoding", "F: X; param1=\"This is ***fun***\"",
ferencd@0 392 p5.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING));
ferencd@0 393
ferencd@0 394 VASSERT_EQ("5.rfc2047", "F: X; param1=\"=?us-ascii*en-us?Q?This_is_***fun***?=\"",
ferencd@0 395 p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY));
ferencd@0 396
ferencd@0 397 VASSERT_EQ("5.rfc2231", "F: X; param1*=us-ascii''This%20is%20***fun***",
ferencd@0 398 p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY));
ferencd@0 399
ferencd@0 400 VASSERT_EQ("5.both", "F: X; "
ferencd@0 401 "param1=\"=?us-ascii*en-us?Q?This_is_***fun***?=\";\r\n "
ferencd@0 402 "param1*=us-ascii''This%20is%20***fun***",
ferencd@0 403 p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047));
ferencd@0 404 }
ferencd@0 405
ferencd@0 406 void testNonStandardEncodedParam()
ferencd@0 407 {
ferencd@0 408 // This syntax is non-standard (expressly prohibited
ferencd@0 409 // by RFC-2047), but is used by Mozilla:
ferencd@0 410 //
ferencd@0 411 // Content-Type: image/png;
ferencd@0 412 // name="=?us-ascii?Q?Logo_VMime=2Epng?="
ferencd@0 413
ferencd@0 414 parameterizedHeaderField p1;
ferencd@0 415 p1.parse("image/png; name=\"=?us-ascii?Q?Logo_VMime=2Epng?=\"");
ferencd@0 416
ferencd@0 417 VASSERT_EQ("1.1", 1, p1.getParameterCount());
ferencd@0 418 VASSERT_EQ("1.2", "name", PARAM_NAME(p1, 0));
ferencd@0 419 VASSERT_EQ("1.3", "Logo VMime.png", PARAM_VALUE(p1, 0));
ferencd@0 420
ferencd@0 421 parameterizedHeaderField p2;
ferencd@0 422 p2.parse("image/png; name=\"Logo =?us-ascii?Q?VMime=2Epng?=\"");
ferencd@0 423
ferencd@0 424 VASSERT_EQ("2.1", 1, p2.getParameterCount());
ferencd@0 425 VASSERT_EQ("2.2", "name", PARAM_NAME(p2, 0));
ferencd@0 426 VASSERT_EQ("2.3", "Logo VMime.png", PARAM_VALUE(p2, 0));
ferencd@0 427 }
ferencd@0 428
ferencd@0 429 // Parse parameters with non-significant whitespaces
ferencd@0 430 void testParseNonSignificantWS()
ferencd@0 431 {
ferencd@0 432 parameterizedHeaderField p1;
ferencd@0 433 p1.parse(" \t X \r\n");
ferencd@0 434
ferencd@0 435 VASSERT_EQ("1.1", "X", FIELD_VALUE(p1));
ferencd@0 436
ferencd@0 437 parameterizedHeaderField p2;
ferencd@0 438 p2.parse(" X ; param1 = value1 \r\n");
ferencd@0 439
ferencd@0 440 VASSERT_EQ("2.1", 1, p2.getParameterCount());
ferencd@0 441 VASSERT_EQ("2.2", "X", FIELD_VALUE(p2));
ferencd@0 442 VASSERT_EQ("2.3", "param1", PARAM_NAME(p2, 0));
ferencd@0 443 VASSERT_EQ("2.4", "value1", PARAM_VALUE(p2, 0));
ferencd@0 444 }
ferencd@0 445
ferencd@0 446 // Encode "tspecials"
ferencd@0 447 void testEncodeTSpecials()
ferencd@0 448 {
ferencd@0 449 VASSERT_EQ(" 1", "p=\"val(ue\"", vmime::make_shared <vmime::parameter>("p", "val(ue")->generate());
ferencd@0 450 VASSERT_EQ(" 2", "p=\"val)ue\"", vmime::make_shared <vmime::parameter>("p", "val)ue")->generate());
ferencd@0 451 VASSERT_EQ(" 3", "p=\"val<ue\"", vmime::make_shared <vmime::parameter>("p", "val<ue")->generate());
ferencd@0 452 VASSERT_EQ(" 4", "p=\"val>ue\"", vmime::make_shared <vmime::parameter>("p", "val>ue")->generate());
ferencd@0 453 VASSERT_EQ(" 5", "p=\"val@ue\"", vmime::make_shared <vmime::parameter>("p", "val@ue")->generate());
ferencd@0 454 VASSERT_EQ(" 6", "p=\"val,ue\"", vmime::make_shared <vmime::parameter>("p", "val,ue")->generate());
ferencd@0 455 VASSERT_EQ(" 7", "p=\"val;ue\"", vmime::make_shared <vmime::parameter>("p", "val;ue")->generate());
ferencd@0 456 VASSERT_EQ(" 8", "p=\"val:ue\"", vmime::make_shared <vmime::parameter>("p", "val:ue")->generate());
ferencd@0 457 VASSERT_EQ(" 9", "p=\"val/ue\"", vmime::make_shared <vmime::parameter>("p", "val/ue")->generate());
ferencd@0 458 VASSERT_EQ("10", "p=\"val[ue\"", vmime::make_shared <vmime::parameter>("p", "val[ue")->generate());
ferencd@0 459 VASSERT_EQ("11", "p=\"val]ue\"", vmime::make_shared <vmime::parameter>("p", "val]ue")->generate());
ferencd@0 460 VASSERT_EQ("12", "p=\"val?ue\"", vmime::make_shared <vmime::parameter>("p", "val?ue")->generate());
ferencd@0 461 VASSERT_EQ("13", "p=\"val=ue\"", vmime::make_shared <vmime::parameter>("p", "val=ue")->generate());
ferencd@0 462 VASSERT_EQ("14", "p=\"val ue\"", vmime::make_shared <vmime::parameter>("p", "val ue")->generate());
ferencd@0 463 VASSERT_EQ("15", "p=\"val\tue\"", vmime::make_shared <vmime::parameter>("p", "val\tue")->generate());
ferencd@0 464 }
ferencd@0 465
ferencd@0 466 // http://sourceforge.net/projects/vmime/forums/forum/237356/topic/3812278
ferencd@0 467 void testEncodeTSpecialsInRFC2231()
ferencd@0 468 {
ferencd@0 469 VASSERT_EQ("1", "filename*=UTF-8''my_file_name_%C3%B6%C3%A4%C3%BC_%281%29.txt",
ferencd@0 470 vmime::make_shared <vmime::parameter>("filename", "my_file_name_\xc3\xb6\xc3\xa4\xc3\xbc_(1).txt")->generate());
ferencd@0 471 }
ferencd@0 472
ferencd@0 473 void testWhitespaceBreaksTheValue()
ferencd@0 474 {
ferencd@0 475 parameterizedHeaderField p;
ferencd@0 476 p.parse("xxx yyy; param1=value1 \r\n");
ferencd@0 477
ferencd@0 478 VASSERT_EQ("count", 1, p.getParameterCount());
ferencd@0 479 VASSERT_EQ("value", "xxx", FIELD_VALUE(p));
ferencd@0 480 VASSERT_EQ("param1.name", "param1", PARAM_NAME(p, 0));
ferencd@0 481 VASSERT_EQ("param1.value", "value1", PARAM_VALUE(p, 0));
ferencd@0 482 }
ferencd@0 483
ferencd@0 484 VMIME_TEST_SUITE_END
ferencd@0 485