UtilTest1.cc 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  1. #include "util.h"
  2. #include <cmath>
  3. #include <cstring>
  4. #include <string>
  5. #include <iostream>
  6. #include <cppunit/extensions/HelperMacros.h>
  7. #include "FixedNumberRandomizer.h"
  8. #include "DlAbortEx.h"
  9. #include "BitfieldMan.h"
  10. #include "ByteArrayDiskWriter.h"
  11. #include "FileEntry.h"
  12. #include "File.h"
  13. #include "array_fun.h"
  14. #include "BufferedFile.h"
  15. #include "TestUtil.h"
  16. #include "SocketCore.h"
  17. namespace aria2 {
  18. class UtilTest1 : public CppUnit::TestFixture {
  19. CPPUNIT_TEST_SUITE(UtilTest1);
  20. CPPUNIT_TEST(testStrip);
  21. CPPUNIT_TEST(testStripIter);
  22. CPPUNIT_TEST(testLstripIter);
  23. CPPUNIT_TEST(testLstripIter_char);
  24. CPPUNIT_TEST(testDivide);
  25. CPPUNIT_TEST(testSplit);
  26. CPPUNIT_TEST(testSplitIter);
  27. CPPUNIT_TEST(testSplitIterM);
  28. CPPUNIT_TEST(testStreq);
  29. CPPUNIT_TEST(testStrieq);
  30. CPPUNIT_TEST(testStrifind);
  31. CPPUNIT_TEST(testEndsWith);
  32. CPPUNIT_TEST(testIendsWith);
  33. CPPUNIT_TEST(testReplace);
  34. CPPUNIT_TEST(testStartsWith);
  35. CPPUNIT_TEST(testIstartsWith);
  36. // may be moved to other helper class in the future.
  37. CPPUNIT_TEST(testGetContentDispositionFilename);
  38. CPPUNIT_TEST(testParseContentDisposition1);
  39. CPPUNIT_TEST(testParseContentDisposition2);
  40. CPPUNIT_TEST_SUITE_END();
  41. private:
  42. public:
  43. void setUp() {}
  44. void testStrip();
  45. void testStripIter();
  46. void testLstripIter();
  47. void testLstripIter_char();
  48. void testDivide();
  49. void testSplit();
  50. void testSplitIter();
  51. void testSplitIterM();
  52. void testStreq();
  53. void testStrieq();
  54. void testStrifind();
  55. void testEndsWith();
  56. void testIendsWith();
  57. void testReplace();
  58. void testStartsWith();
  59. void testIstartsWith();
  60. // may be moved to other helper class in the future.
  61. void testGetContentDispositionFilename();
  62. void testParseContentDisposition1();
  63. void testParseContentDisposition2();
  64. };
  65. CPPUNIT_TEST_SUITE_REGISTRATION(UtilTest1);
  66. void UtilTest1::testStrip()
  67. {
  68. std::string str1 = "aria2";
  69. CPPUNIT_ASSERT_EQUAL(str1, util::strip("aria2"));
  70. CPPUNIT_ASSERT_EQUAL(str1, util::strip(" aria2"));
  71. CPPUNIT_ASSERT_EQUAL(str1, util::strip("aria2 "));
  72. CPPUNIT_ASSERT_EQUAL(str1, util::strip(" aria2 "));
  73. CPPUNIT_ASSERT_EQUAL(str1, util::strip(" aria2 "));
  74. std::string str2 = "aria2 debut";
  75. CPPUNIT_ASSERT_EQUAL(str2, util::strip("aria2 debut"));
  76. CPPUNIT_ASSERT_EQUAL(str2, util::strip(" aria2 debut "));
  77. std::string str3 = "";
  78. CPPUNIT_ASSERT_EQUAL(str3, util::strip(""));
  79. CPPUNIT_ASSERT_EQUAL(str3, util::strip(" "));
  80. CPPUNIT_ASSERT_EQUAL(str3, util::strip(" "));
  81. std::string str4 = "A";
  82. CPPUNIT_ASSERT_EQUAL(str4, util::strip("A"));
  83. CPPUNIT_ASSERT_EQUAL(str4, util::strip(" A "));
  84. CPPUNIT_ASSERT_EQUAL(str4, util::strip(" A "));
  85. }
  86. void UtilTest1::testStripIter()
  87. {
  88. Scip p;
  89. std::string str1 = "aria2";
  90. std::string s = "aria2";
  91. p = util::stripIter(s.begin(), s.end());
  92. CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
  93. s = " aria2";
  94. p = util::stripIter(s.begin(), s.end());
  95. CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
  96. s = "aria2 ";
  97. p = util::stripIter(s.begin(), s.end());
  98. CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
  99. s = " aria2 ";
  100. p = util::stripIter(s.begin(), s.end());
  101. CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
  102. s = " aria2 ";
  103. p = util::stripIter(s.begin(), s.end());
  104. CPPUNIT_ASSERT_EQUAL(str1, std::string(p.first, p.second));
  105. std::string str2 = "aria2 debut";
  106. s = "aria2 debut";
  107. p = util::stripIter(s.begin(), s.end());
  108. CPPUNIT_ASSERT_EQUAL(str2, std::string(p.first, p.second));
  109. s = " aria2 debut ";
  110. p = util::stripIter(s.begin(), s.end());
  111. CPPUNIT_ASSERT_EQUAL(str2, std::string(p.first, p.second));
  112. std::string str3 = "";
  113. s = "";
  114. p = util::stripIter(s.begin(), s.end());
  115. CPPUNIT_ASSERT_EQUAL(str3, std::string(p.first, p.second));
  116. s = " ";
  117. p = util::stripIter(s.begin(), s.end());
  118. CPPUNIT_ASSERT_EQUAL(str3, std::string(p.first, p.second));
  119. s = " ";
  120. p = util::stripIter(s.begin(), s.end());
  121. CPPUNIT_ASSERT_EQUAL(str3, std::string(p.first, p.second));
  122. std::string str4 = "A";
  123. s = "A";
  124. p = util::stripIter(s.begin(), s.end());
  125. CPPUNIT_ASSERT_EQUAL(str4, std::string(p.first, p.second));
  126. s = " A ";
  127. p = util::stripIter(s.begin(), s.end());
  128. CPPUNIT_ASSERT_EQUAL(str4, std::string(p.first, p.second));
  129. s = " A ";
  130. p = util::stripIter(s.begin(), s.end());
  131. CPPUNIT_ASSERT_EQUAL(str4, std::string(p.first, p.second));
  132. }
  133. void UtilTest1::testLstripIter()
  134. {
  135. std::string::iterator r;
  136. std::string s = "foo";
  137. r = util::lstripIter(s.begin(), s.end());
  138. CPPUNIT_ASSERT_EQUAL(std::string("foo"), std::string(r, s.end()));
  139. s = " foo bar ";
  140. r = util::lstripIter(s.begin(), s.end());
  141. CPPUNIT_ASSERT_EQUAL(std::string("foo bar "), std::string(r, s.end()));
  142. s = "f";
  143. r = util::lstripIter(s.begin(), s.end());
  144. CPPUNIT_ASSERT_EQUAL(std::string("f"), std::string(r, s.end()));
  145. s = "foo ";
  146. r = util::lstripIter(s.begin(), s.end());
  147. CPPUNIT_ASSERT_EQUAL(std::string("foo "), std::string(r, s.end()));
  148. }
  149. void UtilTest1::testLstripIter_char()
  150. {
  151. std::string::iterator r;
  152. std::string s = "foo";
  153. r = util::lstripIter(s.begin(), s.end(), '$');
  154. CPPUNIT_ASSERT_EQUAL(std::string("foo"), std::string(r, s.end()));
  155. s = "$$foo$bar$$";
  156. r = util::lstripIter(s.begin(), s.end(), '$');
  157. CPPUNIT_ASSERT_EQUAL(std::string("foo$bar$$"), std::string(r, s.end()));
  158. s = "f";
  159. r = util::lstripIter(s.begin(), s.end(), '$');
  160. CPPUNIT_ASSERT_EQUAL(std::string("f"), std::string(r, s.end()));
  161. s = "foo$$";
  162. r = util::lstripIter(s.begin(), s.end(), '$');
  163. CPPUNIT_ASSERT_EQUAL(std::string("foo$$"), std::string(r, s.end()));
  164. }
  165. void UtilTest1::testDivide()
  166. {
  167. std::string s = "name=value";
  168. auto p1 = util::divide(std::begin(s), std::end(s), '=');
  169. CPPUNIT_ASSERT_EQUAL(std::string("name"),
  170. std::string(p1.first.first, p1.first.second));
  171. CPPUNIT_ASSERT_EQUAL(std::string("value"),
  172. std::string(p1.second.first, p1.second.second));
  173. s = " name = value ";
  174. p1 = util::divide(std::begin(s), std::end(s), '=');
  175. CPPUNIT_ASSERT_EQUAL(std::string("name"),
  176. std::string(p1.first.first, p1.first.second));
  177. CPPUNIT_ASSERT_EQUAL(std::string("value"),
  178. std::string(p1.second.first, p1.second.second));
  179. s = "=value";
  180. p1 = util::divide(std::begin(s), std::end(s), '=');
  181. CPPUNIT_ASSERT_EQUAL(std::string(""),
  182. std::string(p1.first.first, p1.first.second));
  183. CPPUNIT_ASSERT_EQUAL(std::string("value"),
  184. std::string(p1.second.first, p1.second.second));
  185. s = "name=";
  186. p1 = util::divide(std::begin(s), std::end(s), '=');
  187. CPPUNIT_ASSERT_EQUAL(std::string("name"),
  188. std::string(p1.first.first, p1.first.second));
  189. CPPUNIT_ASSERT_EQUAL(std::string(""),
  190. std::string(p1.second.first, p1.second.second));
  191. s = "name";
  192. p1 = util::divide(std::begin(s), std::end(s), '=');
  193. CPPUNIT_ASSERT_EQUAL(std::string("name"),
  194. std::string(p1.first.first, p1.first.second));
  195. CPPUNIT_ASSERT_EQUAL(std::string(""),
  196. std::string(p1.second.first, p1.second.second));
  197. }
  198. void UtilTest1::testSplit()
  199. {
  200. std::vector<std::string> v;
  201. std::string s = "k1; k2;; k3";
  202. util::split(s.begin(), s.end(), std::back_inserter(v), ';', true);
  203. CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
  204. std::vector<std::string>::iterator itr = v.begin();
  205. CPPUNIT_ASSERT_EQUAL(std::string("k1"), *itr++);
  206. CPPUNIT_ASSERT_EQUAL(std::string("k2"), *itr++);
  207. CPPUNIT_ASSERT_EQUAL(std::string("k3"), *itr++);
  208. v.clear();
  209. s = "k1; k2; k3";
  210. util::split(s.begin(), s.end(), std::back_inserter(v), ';');
  211. CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
  212. itr = v.begin();
  213. CPPUNIT_ASSERT_EQUAL(std::string("k1"), *itr++);
  214. CPPUNIT_ASSERT_EQUAL(std::string(" k2"), *itr++);
  215. CPPUNIT_ASSERT_EQUAL(std::string(" k3"), *itr++);
  216. v.clear();
  217. s = "k=v";
  218. util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  219. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  220. itr = v.begin();
  221. CPPUNIT_ASSERT_EQUAL(std::string("k=v"), *itr++);
  222. v.clear();
  223. s = ";;k1;;k2;";
  224. util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  225. CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
  226. itr = v.begin();
  227. CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
  228. CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
  229. CPPUNIT_ASSERT_EQUAL(std::string("k1"), *itr++);
  230. CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
  231. CPPUNIT_ASSERT_EQUAL(std::string("k2"), *itr++);
  232. CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
  233. v.clear();
  234. s = ";;k1;;k2;";
  235. util::split(s.begin(), s.end(), std::back_inserter(v), ';');
  236. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  237. itr = v.begin();
  238. CPPUNIT_ASSERT_EQUAL(std::string("k1"), *itr++);
  239. CPPUNIT_ASSERT_EQUAL(std::string("k2"), *itr++);
  240. v.clear();
  241. s = "k; ";
  242. util::split(s.begin(), s.end(), std::back_inserter(v), ';');
  243. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  244. itr = v.begin();
  245. CPPUNIT_ASSERT_EQUAL(std::string("k"), *itr++);
  246. CPPUNIT_ASSERT_EQUAL(std::string(" "), *itr++);
  247. v.clear();
  248. s = " ";
  249. util::split(s.begin(), s.end(), std::back_inserter(v), ';', true, true);
  250. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  251. CPPUNIT_ASSERT_EQUAL(std::string(""), v[0]);
  252. v.clear();
  253. s = " ";
  254. util::split(s.begin(), s.end(), std::back_inserter(v), ';', true);
  255. CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
  256. v.clear();
  257. s = " ";
  258. util::split(s.begin(), s.end(), std::back_inserter(v), ';');
  259. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  260. CPPUNIT_ASSERT_EQUAL(std::string(" "), v[0]);
  261. v.clear();
  262. s = ";";
  263. util::split(s.begin(), s.end(), std::back_inserter(v), ';');
  264. CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
  265. v.clear();
  266. s = ";";
  267. util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  268. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  269. itr = v.begin();
  270. CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
  271. CPPUNIT_ASSERT_EQUAL(std::string(""), *itr++);
  272. v.clear();
  273. s = "";
  274. util::split(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  275. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  276. CPPUNIT_ASSERT_EQUAL(std::string(""), v[0]);
  277. }
  278. void UtilTest1::testSplitIter()
  279. {
  280. std::vector<Scip> v;
  281. std::string s = "k1; k2;; k3";
  282. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', true);
  283. CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
  284. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  285. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
  286. CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[2].first, v[2].second));
  287. v.clear();
  288. s = "k1; k2; k3";
  289. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
  290. CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
  291. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  292. CPPUNIT_ASSERT_EQUAL(std::string(" k2"),
  293. std::string(v[1].first, v[1].second));
  294. CPPUNIT_ASSERT_EQUAL(std::string(" k3"),
  295. std::string(v[2].first, v[2].second));
  296. v.clear();
  297. s = "k=v";
  298. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  299. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  300. CPPUNIT_ASSERT_EQUAL(std::string("k=v"),
  301. std::string(v[0].first, v[0].second));
  302. v.clear();
  303. s = ";;k1;;k2;";
  304. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  305. CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
  306. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  307. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
  308. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[2].first, v[2].second));
  309. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[3].first, v[3].second));
  310. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[4].first, v[4].second));
  311. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[5].first, v[5].second));
  312. v.clear();
  313. s = ";;k1;;k2;";
  314. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
  315. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  316. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  317. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
  318. v.clear();
  319. s = "k; ";
  320. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
  321. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  322. CPPUNIT_ASSERT_EQUAL(std::string("k"), std::string(v[0].first, v[0].second));
  323. CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[1].first, v[1].second));
  324. v.clear();
  325. s = " ";
  326. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', true, true);
  327. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  328. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  329. v.clear();
  330. s = " ";
  331. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', true);
  332. CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
  333. v.clear();
  334. s = " ";
  335. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
  336. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  337. CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[0].first, v[0].second));
  338. v.clear();
  339. s = ";";
  340. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';');
  341. CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
  342. v.clear();
  343. s = ";";
  344. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  345. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  346. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  347. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
  348. v.clear();
  349. s = "";
  350. util::splitIter(s.begin(), s.end(), std::back_inserter(v), ';', false, true);
  351. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  352. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  353. }
  354. void UtilTest1::testSplitIterM()
  355. {
  356. const char d[] = ";";
  357. const char md[] = "; ";
  358. std::vector<Scip> v;
  359. std::string s = "k1; k2;; k3";
  360. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, true);
  361. CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
  362. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  363. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
  364. CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[2].first, v[2].second));
  365. v.clear();
  366. s = "k1; k2; k3";
  367. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
  368. CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
  369. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  370. CPPUNIT_ASSERT_EQUAL(std::string(" k2"),
  371. std::string(v[1].first, v[1].second));
  372. CPPUNIT_ASSERT_EQUAL(std::string(" k3"),
  373. std::string(v[2].first, v[2].second));
  374. v.clear();
  375. s = "k1; k2; k3";
  376. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), md);
  377. CPPUNIT_ASSERT_EQUAL((size_t)3, v.size());
  378. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  379. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
  380. CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[2].first, v[2].second));
  381. v.clear();
  382. s = "k1; k2; k3;";
  383. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), md, false, true);
  384. CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
  385. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  386. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
  387. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[2].first, v[2].second));
  388. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[3].first, v[3].second));
  389. CPPUNIT_ASSERT_EQUAL(std::string("k3"), std::string(v[4].first, v[4].second));
  390. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[5].first, v[5].second));
  391. v.clear();
  392. s = "k=v";
  393. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
  394. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  395. CPPUNIT_ASSERT_EQUAL(std::string("k=v"),
  396. std::string(v[0].first, v[0].second));
  397. v.clear();
  398. s = ";;k1;;k2;";
  399. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
  400. CPPUNIT_ASSERT_EQUAL((size_t)6, v.size());
  401. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  402. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
  403. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[2].first, v[2].second));
  404. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[3].first, v[3].second));
  405. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[4].first, v[4].second));
  406. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[5].first, v[5].second));
  407. v.clear();
  408. s = ";;k1;;k2;";
  409. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
  410. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  411. CPPUNIT_ASSERT_EQUAL(std::string("k1"), std::string(v[0].first, v[0].second));
  412. CPPUNIT_ASSERT_EQUAL(std::string("k2"), std::string(v[1].first, v[1].second));
  413. v.clear();
  414. s = "k; ";
  415. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
  416. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  417. CPPUNIT_ASSERT_EQUAL(std::string("k"), std::string(v[0].first, v[0].second));
  418. CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[1].first, v[1].second));
  419. v.clear();
  420. s = " ";
  421. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, true, true);
  422. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  423. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  424. v.clear();
  425. s = " ";
  426. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, true);
  427. CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
  428. v.clear();
  429. s = " ";
  430. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
  431. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  432. CPPUNIT_ASSERT_EQUAL(std::string(" "), std::string(v[0].first, v[0].second));
  433. v.clear();
  434. s = ";";
  435. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d);
  436. CPPUNIT_ASSERT_EQUAL((size_t)0, v.size());
  437. v.clear();
  438. s = ";";
  439. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
  440. CPPUNIT_ASSERT_EQUAL((size_t)2, v.size());
  441. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  442. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[1].first, v[1].second));
  443. v.clear();
  444. s = "";
  445. util::splitIterM(s.begin(), s.end(), std::back_inserter(v), d, false, true);
  446. CPPUNIT_ASSERT_EQUAL((size_t)1, v.size());
  447. CPPUNIT_ASSERT_EQUAL(std::string(""), std::string(v[0].first, v[0].second));
  448. }
  449. void UtilTest1::testEndsWith()
  450. {
  451. std::string target = "abcdefg";
  452. std::string part = "fg";
  453. CPPUNIT_ASSERT(
  454. util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  455. target = "abdefg";
  456. part = "g";
  457. CPPUNIT_ASSERT(
  458. util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  459. target = "abdefg";
  460. part = "eg";
  461. CPPUNIT_ASSERT(
  462. !util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  463. target = "g";
  464. part = "eg";
  465. CPPUNIT_ASSERT(
  466. !util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  467. target = "g";
  468. part = "g";
  469. CPPUNIT_ASSERT(
  470. util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  471. target = "g";
  472. part = "";
  473. CPPUNIT_ASSERT(
  474. util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  475. target = "";
  476. part = "";
  477. CPPUNIT_ASSERT(
  478. util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  479. target = "";
  480. part = "g";
  481. CPPUNIT_ASSERT(
  482. !util::endsWith(target.begin(), target.end(), part.begin(), part.end()));
  483. }
  484. void UtilTest1::testIendsWith()
  485. {
  486. std::string target = "abcdefg";
  487. std::string part = "Fg";
  488. CPPUNIT_ASSERT(
  489. util::iendsWith(target.begin(), target.end(), part.begin(), part.end()));
  490. target = "abdefg";
  491. part = "ef";
  492. CPPUNIT_ASSERT(
  493. !util::iendsWith(target.begin(), target.end(), part.begin(), part.end()));
  494. }
  495. void UtilTest1::testStreq()
  496. {
  497. std::string s1, s2;
  498. s1 = "foo";
  499. s2 = "foo";
  500. CPPUNIT_ASSERT(util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  501. CPPUNIT_ASSERT(util::streq(s1.begin(), s1.end(), s2.c_str()));
  502. s2 = "fooo";
  503. CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  504. CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.c_str()));
  505. s2 = "fo";
  506. CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  507. CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.c_str()));
  508. s2 = "";
  509. CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  510. CPPUNIT_ASSERT(!util::streq(s1.begin(), s1.end(), s2.c_str()));
  511. s1 = "";
  512. CPPUNIT_ASSERT(util::streq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  513. CPPUNIT_ASSERT(util::streq(s1.begin(), s1.end(), s2.c_str()));
  514. }
  515. void UtilTest1::testStrieq()
  516. {
  517. std::string s1, s2;
  518. s1 = "foo";
  519. s2 = "foo";
  520. CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  521. CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.c_str()));
  522. s1 = "FoO";
  523. s2 = "fOo";
  524. CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  525. CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.c_str()));
  526. s2 = "fooo";
  527. CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  528. CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.c_str()));
  529. s2 = "fo";
  530. CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  531. CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.c_str()));
  532. s2 = "";
  533. CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  534. CPPUNIT_ASSERT(!util::strieq(s1.begin(), s1.end(), s2.c_str()));
  535. s1 = "";
  536. CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.begin(), s2.end()));
  537. CPPUNIT_ASSERT(util::strieq(s1.begin(), s1.end(), s2.c_str()));
  538. }
  539. void UtilTest1::testStrifind()
  540. {
  541. std::string s1, s2;
  542. s1 = "yamagakani mukashi wo toheba hARU no tuki";
  543. s2 = "HaRu";
  544. CPPUNIT_ASSERT(util::strifind(s1.begin(), s1.end(), s2.begin(), s2.end()) !=
  545. s1.end());
  546. s2 = "aki";
  547. CPPUNIT_ASSERT(util::strifind(s1.begin(), s1.end(), s2.begin(), s2.end()) ==
  548. s1.end());
  549. s1 = "h";
  550. s2 = "HH";
  551. CPPUNIT_ASSERT(util::strifind(s1.begin(), s1.end(), s2.begin(), s2.end()) ==
  552. s1.end());
  553. }
  554. void UtilTest1::testReplace()
  555. {
  556. CPPUNIT_ASSERT_EQUAL(std::string("abc\n"),
  557. util::replace("abc\r\n", "\r", ""));
  558. CPPUNIT_ASSERT_EQUAL(std::string("abc"),
  559. util::replace("abc\r\n", "\r\n", ""));
  560. CPPUNIT_ASSERT_EQUAL(std::string(""), util::replace("", "\r\n", ""));
  561. CPPUNIT_ASSERT_EQUAL(std::string("abc"), util::replace("abc", "", "a"));
  562. CPPUNIT_ASSERT_EQUAL(std::string("xbc"), util::replace("abc", "a", "x"));
  563. }
  564. void UtilTest1::testStartsWith()
  565. {
  566. std::string target;
  567. std::string part;
  568. target = "abcdefg";
  569. part = "abc";
  570. CPPUNIT_ASSERT(
  571. util::startsWith(target.begin(), target.end(), part.begin(), part.end()));
  572. CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(), part.c_str()));
  573. target = "abcdefg";
  574. part = "abx";
  575. CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(), part.begin(),
  576. part.end()));
  577. CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(), part.c_str()));
  578. target = "abcdefg";
  579. part = "bcd";
  580. CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(), part.begin(),
  581. part.end()));
  582. CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(), part.c_str()));
  583. target = "";
  584. part = "a";
  585. CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(), part.begin(),
  586. part.end()));
  587. CPPUNIT_ASSERT(!util::startsWith(target.begin(), target.end(), part.c_str()));
  588. target = "";
  589. part = "";
  590. CPPUNIT_ASSERT(
  591. util::startsWith(target.begin(), target.end(), part.begin(), part.end()));
  592. CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(), part.c_str()));
  593. target = "a";
  594. part = "";
  595. CPPUNIT_ASSERT(
  596. util::startsWith(target.begin(), target.end(), part.begin(), part.end()));
  597. CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(), part.c_str()));
  598. target = "a";
  599. part = "a";
  600. CPPUNIT_ASSERT(
  601. util::startsWith(target.begin(), target.end(), part.begin(), part.end()));
  602. CPPUNIT_ASSERT(util::startsWith(target.begin(), target.end(), part.c_str()));
  603. }
  604. void UtilTest1::testIstartsWith()
  605. {
  606. std::string target;
  607. std::string part;
  608. target = "abcdefg";
  609. part = "aBc";
  610. CPPUNIT_ASSERT(util::istartsWith(target.begin(), target.end(), part.begin(),
  611. part.end()));
  612. CPPUNIT_ASSERT(util::istartsWith(target.begin(), target.end(), part.c_str()));
  613. target = "abcdefg";
  614. part = "abx";
  615. CPPUNIT_ASSERT(!util::istartsWith(target.begin(), target.end(), part.begin(),
  616. part.end()));
  617. CPPUNIT_ASSERT(
  618. !util::istartsWith(target.begin(), target.end(), part.c_str()));
  619. }
  620. void UtilTest1::testGetContentDispositionFilename()
  621. {
  622. std::string val;
  623. val = "attachment; filename=\"aria2.tar.bz2\"";
  624. CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"),
  625. util::getContentDispositionFilename(val));
  626. val = "attachment; filename=\"\"";
  627. CPPUNIT_ASSERT_EQUAL(std::string(""),
  628. util::getContentDispositionFilename(val));
  629. val = "attachment; filename=\"";
  630. CPPUNIT_ASSERT_EQUAL(std::string(""),
  631. util::getContentDispositionFilename(val));
  632. val = "attachment; filename= \" aria2.tar.bz2 \"";
  633. CPPUNIT_ASSERT_EQUAL(std::string(" aria2.tar.bz2 "),
  634. util::getContentDispositionFilename(val));
  635. val = "attachment; filename=dir/file";
  636. CPPUNIT_ASSERT_EQUAL(std::string(""),
  637. util::getContentDispositionFilename(val));
  638. val = "attachment; filename=dir\\file";
  639. CPPUNIT_ASSERT_EQUAL(std::string(""),
  640. util::getContentDispositionFilename(val));
  641. val = "attachment; filename=\"dir/file\"";
  642. CPPUNIT_ASSERT_EQUAL(std::string(""),
  643. util::getContentDispositionFilename(val));
  644. val = "attachment; filename=\"dir\\\\file\"";
  645. CPPUNIT_ASSERT_EQUAL(std::string(""),
  646. util::getContentDispositionFilename(val));
  647. val = "attachment; filename=\"/etc/passwd\"";
  648. CPPUNIT_ASSERT_EQUAL(std::string(""),
  649. util::getContentDispositionFilename(val));
  650. val = "attachment; filename=\"..\"";
  651. CPPUNIT_ASSERT_EQUAL(std::string(""),
  652. util::getContentDispositionFilename(val));
  653. val = "attachment; filename=..";
  654. CPPUNIT_ASSERT_EQUAL(std::string(""),
  655. util::getContentDispositionFilename(val));
  656. // Unescaping %2E%2E%2F produces "../". But since we won't unescape,
  657. // we just accept it as is.
  658. val = "attachment; filename=\"%2E%2E%2Ffoo.html\"";
  659. CPPUNIT_ASSERT_EQUAL(std::string("%2E%2E%2Ffoo.html"),
  660. util::getContentDispositionFilename(val));
  661. // iso-8859-1 string will be converted to utf-8.
  662. val = "attachment; filename*=iso-8859-1''foo-%E4.html";
  663. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  664. util::getContentDispositionFilename(val));
  665. val = "attachment; filename*= UTF-8''foo-%c3%a4.html";
  666. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  667. util::getContentDispositionFilename(val));
  668. // iso-8859-1 string will be converted to utf-8.
  669. val = "attachment; filename=\"foo-%E4.html\"";
  670. val = util::percentDecode(val.begin(), val.end());
  671. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  672. util::getContentDispositionFilename(val));
  673. }
  674. void UtilTest1::testParseContentDisposition1()
  675. {
  676. char dest[1_k];
  677. size_t destlen = sizeof(dest);
  678. const char* cs;
  679. size_t cslen;
  680. std::string val;
  681. // test cases from http://greenbytes.de/tech/tc2231/
  682. // inlonly
  683. val = "inline";
  684. CPPUNIT_ASSERT_EQUAL(
  685. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  686. val.c_str(), val.size()));
  687. // inlonlyquoted
  688. val = "\"inline\"";
  689. CPPUNIT_ASSERT_EQUAL(
  690. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  691. val.c_str(), val.size()));
  692. // inlwithasciifilename
  693. val = "inline; filename=\"foo.html\"";
  694. CPPUNIT_ASSERT_EQUAL(
  695. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  696. val.c_str(), val.size()));
  697. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  698. std::string(&dest[0], &dest[8]));
  699. // inlwithfnattach
  700. val = "inline; filename=\"Not an attachment!\"";
  701. CPPUNIT_ASSERT_EQUAL(
  702. (ssize_t)18, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  703. val.c_str(), val.size()));
  704. CPPUNIT_ASSERT_EQUAL(std::string("Not an attachment!"),
  705. std::string(&dest[0], &dest[18]));
  706. // inlwithasciifilenamepdf
  707. val = "inline; filename=\"foo.pdf\"";
  708. CPPUNIT_ASSERT_EQUAL(
  709. (ssize_t)7, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  710. val.c_str(), val.size()));
  711. CPPUNIT_ASSERT_EQUAL(std::string("foo.pdf"), std::string(&dest[0], &dest[7]));
  712. // attwithasciifilename25
  713. val = "attachment; filename=\"0000000000111111111122222\"";
  714. CPPUNIT_ASSERT_EQUAL(
  715. (ssize_t)25, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  716. val.c_str(), val.size()));
  717. CPPUNIT_ASSERT_EQUAL(std::string("0000000000111111111122222"),
  718. std::string(&dest[0], &dest[25]));
  719. // attwithasciifilename35
  720. val = "attachment; filename=\"00000000001111111111222222222233333\"";
  721. CPPUNIT_ASSERT_EQUAL(
  722. (ssize_t)35, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  723. val.c_str(), val.size()));
  724. CPPUNIT_ASSERT_EQUAL(std::string("00000000001111111111222222222233333"),
  725. std::string(&dest[0], &dest[35]));
  726. // attwithasciifnescapedchar
  727. val = "attachment; filename=\"f\\oo.html\"";
  728. CPPUNIT_ASSERT_EQUAL(
  729. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  730. val.c_str(), val.size()));
  731. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  732. std::string(&dest[0], &dest[8]));
  733. // attwithasciifnescapedquote
  734. val = "attachment; filename=\"\\\"quoting\\\" tested.html\"";
  735. CPPUNIT_ASSERT_EQUAL(
  736. (ssize_t)21, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  737. val.c_str(), val.size()));
  738. CPPUNIT_ASSERT_EQUAL(std::string("\"quoting\" tested.html"),
  739. std::string(&dest[0], &dest[21]));
  740. // attwithquotedsemicolon
  741. val = "attachment; filename=\"Here's a semicolon;.html\"";
  742. CPPUNIT_ASSERT_EQUAL(
  743. (ssize_t)24, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  744. val.c_str(), val.size()));
  745. CPPUNIT_ASSERT_EQUAL(std::string("Here's a semicolon;.html"),
  746. std::string(&dest[0], &dest[24]));
  747. // attwithfilenameandextparam
  748. val = "attachment; foo=\"bar\"; filename=\"foo.html\"";
  749. CPPUNIT_ASSERT_EQUAL(
  750. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  751. val.c_str(), val.size()));
  752. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  753. std::string(&dest[0], &dest[8]));
  754. // attwithfilenameandextparamescaped
  755. val = "attachment; foo=\"\\\"\\\\\";filename=\"foo.html\"";
  756. CPPUNIT_ASSERT_EQUAL(
  757. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  758. val.c_str(), val.size()));
  759. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  760. std::string(&dest[0], &dest[8]));
  761. // attwithasciifilenameucase
  762. val = "attachment; FILENAME=\"foo.html\"";
  763. CPPUNIT_ASSERT_EQUAL(
  764. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  765. val.c_str(), val.size()));
  766. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  767. std::string(&dest[0], &dest[8]));
  768. // attwithasciifilenamenq
  769. val = "attachment; filename=foo.html";
  770. CPPUNIT_ASSERT_EQUAL(
  771. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  772. val.c_str(), val.size()));
  773. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  774. std::string(&dest[0], &dest[8]));
  775. // attwithtokfncommanq
  776. val = "attachment; filename=foo,bar.html";
  777. CPPUNIT_ASSERT_EQUAL(
  778. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  779. val.c_str(), val.size()));
  780. // attwithasciifilenamenqs
  781. val = "attachment; filename=foo.html ;";
  782. CPPUNIT_ASSERT_EQUAL(
  783. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  784. val.c_str(), val.size()));
  785. // attemptyparam
  786. val = "attachment; ;filename=foo";
  787. CPPUNIT_ASSERT_EQUAL(
  788. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  789. val.c_str(), val.size()));
  790. // attwithasciifilenamenqws
  791. val = "attachment; filename=foo bar.html";
  792. CPPUNIT_ASSERT_EQUAL(
  793. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  794. val.c_str(), val.size()));
  795. // attwithfntokensq
  796. val = "attachment; filename='foo.bar'";
  797. CPPUNIT_ASSERT_EQUAL(
  798. (ssize_t)9, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  799. val.c_str(), val.size()));
  800. CPPUNIT_ASSERT_EQUAL(std::string("'foo.bar'"),
  801. std::string(&dest[0], &dest[9]));
  802. // attwithisofnplain
  803. // attachment; filename="foo-ä.html"
  804. val = "attachment; filename=\"foo-%E4.html\"";
  805. val = util::percentDecode(val.begin(), val.end());
  806. CPPUNIT_ASSERT_EQUAL(
  807. (ssize_t)10, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  808. val.c_str(), val.size()));
  809. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  810. util::iso8859p1ToUtf8(std::string(&dest[0], &dest[10])));
  811. // attwithutf8fnplain
  812. // attachment; filename="foo-ä.html"
  813. val = "attachment; filename=\"foo-%C3%A4.html\"";
  814. val = util::percentDecode(val.begin(), val.end());
  815. CPPUNIT_ASSERT_EQUAL(
  816. (ssize_t)11, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  817. val.c_str(), val.size()));
  818. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  819. util::iso8859p1ToUtf8(std::string(&dest[0], &dest[11])));
  820. // attwithfnrawpctenca
  821. val = "attachment; filename=\"foo-%41.html\"";
  822. CPPUNIT_ASSERT_EQUAL(
  823. (ssize_t)12, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  824. val.c_str(), val.size()));
  825. CPPUNIT_ASSERT_EQUAL(std::string("foo-%41.html"),
  826. std::string(&dest[0], &dest[12]));
  827. // attwithfnusingpct
  828. val = "attachment; filename=\"50%.html\"";
  829. CPPUNIT_ASSERT_EQUAL(
  830. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  831. val.c_str(), val.size()));
  832. CPPUNIT_ASSERT_EQUAL(std::string("50%.html"),
  833. std::string(&dest[0], &dest[8]));
  834. // attwithfnrawpctencaq
  835. val = "attachment; filename=\"foo-%\\41.html\"";
  836. CPPUNIT_ASSERT_EQUAL(
  837. (ssize_t)12, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  838. val.c_str(), val.size()));
  839. CPPUNIT_ASSERT_EQUAL(std::string("foo-%41.html"),
  840. std::string(&dest[0], &dest[12]));
  841. // attwithnamepct
  842. val = "attachment; name=\"foo-%41.html\"";
  843. CPPUNIT_ASSERT_EQUAL(
  844. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  845. val.c_str(), val.size()));
  846. // attwithfilenamepctandiso
  847. // attachment; filename="ä-%41.html"
  848. val = "attachment; filename=\"%E4-%2541.html\"";
  849. val = util::percentDecode(val.begin(), val.end());
  850. CPPUNIT_ASSERT_EQUAL(
  851. (ssize_t)10, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  852. val.c_str(), val.size()));
  853. CPPUNIT_ASSERT_EQUAL(std::string("ä-%41.html"),
  854. util::iso8859p1ToUtf8(std::string(&dest[0], &dest[10])));
  855. // attwithfnrawpctenclong
  856. val = "attachment; filename=\"foo-%c3%a4-%e2%82%ac.html\"";
  857. CPPUNIT_ASSERT_EQUAL(
  858. (ssize_t)25, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  859. val.c_str(), val.size()));
  860. CPPUNIT_ASSERT_EQUAL(std::string("foo-%c3%a4-%e2%82%ac.html"),
  861. std::string(&dest[0], &dest[25]));
  862. // attwithasciifilenamews1
  863. val = "attachment; filename =\"foo.html\"";
  864. CPPUNIT_ASSERT_EQUAL(
  865. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  866. val.c_str(), val.size()));
  867. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  868. std::string(&dest[0], &dest[8]));
  869. // attwith2filenames
  870. val = "attachment; filename=\"foo.html\"; filename=\"bar.html\"";
  871. CPPUNIT_ASSERT_EQUAL(
  872. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  873. val.c_str(), val.size()));
  874. // attfnbrokentoken
  875. val = "attachment; filename=foo[1](2).html";
  876. CPPUNIT_ASSERT_EQUAL(
  877. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  878. val.c_str(), val.size()));
  879. // attfnbrokentokeniso
  880. val = "attachment; filename=foo-%E4.html";
  881. val = util::percentDecode(val.begin(), val.end());
  882. CPPUNIT_ASSERT_EQUAL(
  883. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  884. val.c_str(), val.size()));
  885. // attfnbrokentokenutf
  886. // attachment; filename=foo-ä.html
  887. val = "attachment; filename=foo-ä.html";
  888. CPPUNIT_ASSERT_EQUAL(
  889. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  890. val.c_str(), val.size()));
  891. // attmissingdisposition
  892. val = "filename=foo.html";
  893. CPPUNIT_ASSERT_EQUAL(
  894. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  895. val.c_str(), val.size()));
  896. // attmissingdisposition2
  897. val = "x=y; filename=foo.html";
  898. CPPUNIT_ASSERT_EQUAL(
  899. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  900. val.c_str(), val.size()));
  901. // attmissingdisposition3
  902. val = "\"foo; filename=bar;baz\"; filename=qux";
  903. CPPUNIT_ASSERT_EQUAL(
  904. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  905. val.c_str(), val.size()));
  906. // attmissingdisposition4
  907. val = "filename=foo.html, filename=bar.html";
  908. CPPUNIT_ASSERT_EQUAL(
  909. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  910. val.c_str(), val.size()));
  911. // emptydisposition
  912. val = "; filename=foo.html";
  913. CPPUNIT_ASSERT_EQUAL(
  914. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  915. val.c_str(), val.size()));
  916. // doublecolon
  917. val = ": inline; attachment; filename=foo.html";
  918. CPPUNIT_ASSERT_EQUAL(
  919. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  920. val.c_str(), val.size()));
  921. // attandinline
  922. val = "inline; attachment; filename=foo.html";
  923. CPPUNIT_ASSERT_EQUAL(
  924. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  925. val.c_str(), val.size()));
  926. // attandinline2
  927. val = "attachment; inline; filename=foo.html";
  928. CPPUNIT_ASSERT_EQUAL(
  929. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  930. val.c_str(), val.size()));
  931. // attbrokenquotedfn
  932. val = "attachment; filename=\"foo.html\".txt";
  933. CPPUNIT_ASSERT_EQUAL(
  934. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  935. val.c_str(), val.size()));
  936. // attbrokenquotedfn2
  937. val = "attachment; filename=\"bar";
  938. CPPUNIT_ASSERT_EQUAL(
  939. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  940. val.c_str(), val.size()));
  941. // attbrokenquotedfn3
  942. val = "attachment; filename=foo\"bar;baz\"qux";
  943. CPPUNIT_ASSERT_EQUAL(
  944. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  945. val.c_str(), val.size()));
  946. // attmultinstances
  947. val = "attachment; filename=foo.html, attachment; filename=bar.html";
  948. CPPUNIT_ASSERT_EQUAL(
  949. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  950. val.c_str(), val.size()));
  951. }
  952. void UtilTest1::testParseContentDisposition2()
  953. {
  954. char dest[1_k];
  955. size_t destlen = sizeof(dest);
  956. const char* cs;
  957. size_t cslen;
  958. std::string val;
  959. // test cases from http://greenbytes.de/tech/tc2231/
  960. // attmissingdelim
  961. val = "attachment; foo=foo filename=bar";
  962. CPPUNIT_ASSERT_EQUAL(
  963. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  964. val.c_str(), val.size()));
  965. // attmissingdelim2
  966. val = "attachment; filename=bar foo=foo ";
  967. CPPUNIT_ASSERT_EQUAL(
  968. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  969. val.c_str(), val.size()));
  970. // attmissingdelim3
  971. val = "attachment filename=bar";
  972. CPPUNIT_ASSERT_EQUAL(
  973. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  974. val.c_str(), val.size()));
  975. // attreversed
  976. val = "filename=foo.html; attachment";
  977. CPPUNIT_ASSERT_EQUAL(
  978. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  979. val.c_str(), val.size()));
  980. // attconfusedparam
  981. val = "attachment; xfilename=foo.html";
  982. CPPUNIT_ASSERT_EQUAL(
  983. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  984. val.c_str(), val.size()));
  985. // attabspath
  986. val = "attachment; filename=\"/foo.html\"";
  987. CPPUNIT_ASSERT_EQUAL(
  988. (ssize_t)9, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  989. val.c_str(), val.size()));
  990. CPPUNIT_ASSERT_EQUAL(std::string("/foo.html"),
  991. std::string(&dest[0], &dest[9]));
  992. // attabspathwin
  993. val = "attachment; filename=\"\\\\foo.html\"";
  994. CPPUNIT_ASSERT_EQUAL(
  995. (ssize_t)9, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  996. val.c_str(), val.size()));
  997. CPPUNIT_ASSERT_EQUAL(std::string("\\foo.html"),
  998. std::string(&dest[0], &dest[9]));
  999. // attcdate
  1000. val = "attachment; creation-date=\"Wed, 12 Feb 1997 16:29:51 -0500\"";
  1001. CPPUNIT_ASSERT_EQUAL(
  1002. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1003. val.c_str(), val.size()));
  1004. // dispext
  1005. val = "foobar";
  1006. CPPUNIT_ASSERT_EQUAL(
  1007. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1008. val.c_str(), val.size()));
  1009. // dispextbadfn
  1010. val = "attachment; example=\"filename=example.txt\"";
  1011. CPPUNIT_ASSERT_EQUAL(
  1012. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1013. val.c_str(), val.size()));
  1014. // attwithisofn2231iso
  1015. val = "attachment; filename*=iso-8859-1''foo-%E4.html";
  1016. CPPUNIT_ASSERT_EQUAL(
  1017. (ssize_t)10, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1018. val.c_str(), val.size()));
  1019. CPPUNIT_ASSERT_EQUAL(std::string("iso-8859-1"), std::string(cs, cslen));
  1020. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  1021. util::iso8859p1ToUtf8(std::string(&dest[0], &dest[10])));
  1022. // attwithfn2231utf8
  1023. val = "attachment; filename*=UTF-8''foo-%c3%a4-%e2%82%ac.html";
  1024. CPPUNIT_ASSERT_EQUAL(
  1025. (ssize_t)15, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1026. val.c_str(), val.size()));
  1027. CPPUNIT_ASSERT_EQUAL(std::string("UTF-8"), std::string(cs, cslen));
  1028. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä-€.html"),
  1029. std::string(&dest[0], &dest[15]));
  1030. // attwithfn2231noc
  1031. val = "attachment; filename*=''foo-%c3%a4-%e2%82%ac.html";
  1032. CPPUNIT_ASSERT_EQUAL(
  1033. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1034. val.c_str(), val.size()));
  1035. // attwithfn2231utf8comp
  1036. val = "attachment; filename*=UTF-8''foo-a%cc%88.html";
  1037. CPPUNIT_ASSERT_EQUAL(
  1038. (ssize_t)12, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1039. val.c_str(), val.size()));
  1040. val = "foo-a%cc%88.html";
  1041. CPPUNIT_ASSERT_EQUAL(std::string(util::percentDecode(val.begin(), val.end())),
  1042. std::string(&dest[0], &dest[12]));
  1043. // attwithfn2231utf8-bad
  1044. val = "attachment; filename*=iso-8859-1''foo-%c3%a4-%e2%82%ac.html";
  1045. CPPUNIT_ASSERT_EQUAL(
  1046. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1047. val.c_str(), val.size()));
  1048. // attwithfn2231iso-bad
  1049. val = "attachment; filename*=utf-8''foo-%E4.html";
  1050. CPPUNIT_ASSERT_EQUAL(
  1051. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1052. val.c_str(), val.size()));
  1053. // attwithfn2231ws1
  1054. val = "attachment; filename *=UTF-8''foo-%c3%a4.html";
  1055. CPPUNIT_ASSERT_EQUAL(
  1056. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1057. val.c_str(), val.size()));
  1058. // attwithfn2231ws2
  1059. val = "attachment; filename*= UTF-8''foo-%c3%a4.html";
  1060. CPPUNIT_ASSERT_EQUAL(
  1061. (ssize_t)11, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1062. val.c_str(), val.size()));
  1063. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  1064. std::string(&dest[0], &dest[11]));
  1065. // attwithfn2231ws3
  1066. val = "attachment; filename* =UTF-8''foo-%c3%a4.html";
  1067. CPPUNIT_ASSERT_EQUAL(
  1068. (ssize_t)11, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1069. val.c_str(), val.size()));
  1070. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  1071. std::string(&dest[0], &dest[11]));
  1072. // attwithfn2231quot
  1073. val = "attachment; filename*=\"UTF-8''foo-%c3%a4.html\"";
  1074. CPPUNIT_ASSERT_EQUAL(
  1075. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1076. val.c_str(), val.size()));
  1077. // attwithfn2231quot2
  1078. val = "attachment; filename*=\"foo%20bar.html\"";
  1079. CPPUNIT_ASSERT_EQUAL(
  1080. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1081. val.c_str(), val.size()));
  1082. // attwithfn2231singleqmissing
  1083. val = "attachment; filename*=UTF-8'foo-%c3%a4.html";
  1084. CPPUNIT_ASSERT_EQUAL(
  1085. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1086. val.c_str(), val.size()));
  1087. // attwithfn2231nbadpct1
  1088. val = "attachment; filename*=UTF-8''foo%";
  1089. CPPUNIT_ASSERT_EQUAL(
  1090. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1091. val.c_str(), val.size()));
  1092. // attwithfn2231nbadpct2
  1093. val = "attachment; filename*=UTF-8''f%oo.html";
  1094. CPPUNIT_ASSERT_EQUAL(
  1095. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1096. val.c_str(), val.size()));
  1097. // attwithfn2231dpct
  1098. val = "attachment; filename*=UTF-8''A-%2541.html";
  1099. CPPUNIT_ASSERT_EQUAL(
  1100. (ssize_t)10, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1101. val.c_str(), val.size()));
  1102. CPPUNIT_ASSERT_EQUAL(std::string("A-%41.html"),
  1103. std::string(&dest[0], &dest[10]));
  1104. // attwithfn2231abspathdisguised
  1105. val = "attachment; filename*=UTF-8''%5cfoo.html";
  1106. CPPUNIT_ASSERT_EQUAL(
  1107. (ssize_t)9, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1108. val.c_str(), val.size()));
  1109. CPPUNIT_ASSERT_EQUAL(std::string("\\foo.html"),
  1110. std::string(&dest[0], &dest[9]));
  1111. // attfnboth
  1112. val =
  1113. "attachment; filename=\"foo-ae.html\"; filename*=UTF-8''foo-%c3%a4.html";
  1114. CPPUNIT_ASSERT_EQUAL(
  1115. (ssize_t)11, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1116. val.c_str(), val.size()));
  1117. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  1118. std::string(&dest[0], &dest[11]));
  1119. // attfnboth2
  1120. val =
  1121. "attachment; filename*=UTF-8''foo-%c3%a4.html; filename=\"foo-ae.html\"";
  1122. CPPUNIT_ASSERT_EQUAL(
  1123. (ssize_t)11, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1124. val.c_str(), val.size()));
  1125. CPPUNIT_ASSERT_EQUAL(std::string("foo-ä.html"),
  1126. std::string(&dest[0], &dest[11]));
  1127. // attfnboth3
  1128. val = "attachment; filename*0*=ISO-8859-15''euro-sign%3d%a4; "
  1129. "filename*=ISO-8859-1''currency-sign%3d%a4";
  1130. CPPUNIT_ASSERT_EQUAL(
  1131. (ssize_t)15, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1132. val.c_str(), val.size()));
  1133. CPPUNIT_ASSERT_EQUAL(std::string("ISO-8859-1"), std::string(cs, cslen));
  1134. CPPUNIT_ASSERT_EQUAL(std::string("currency-sign=¤"),
  1135. util::iso8859p1ToUtf8(std::string(&dest[0], &dest[15])));
  1136. // attnewandfn
  1137. val = "attachment; foobar=x; filename=\"foo.html\"";
  1138. CPPUNIT_ASSERT_EQUAL(
  1139. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1140. val.c_str(), val.size()));
  1141. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1142. std::string(&dest[0], &dest[8]));
  1143. // attrfc2047token
  1144. val = "attachment; filename==?ISO-8859-1?Q?foo-=E4.html?=";
  1145. CPPUNIT_ASSERT_EQUAL(
  1146. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1147. val.c_str(), val.size()));
  1148. // attrfc2047quoted
  1149. val = "attachment; filename=\"=?ISO-8859-1?Q?foo-=E4.html?=\"";
  1150. CPPUNIT_ASSERT_EQUAL(
  1151. (ssize_t)29, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1152. val.c_str(), val.size()));
  1153. CPPUNIT_ASSERT_EQUAL(std::string("=?ISO-8859-1?Q?foo-=E4.html?="),
  1154. std::string(&dest[0], &dest[29]));
  1155. // aria2 original testcases
  1156. // zero-length filename. token cannot be empty, so this is invalid.
  1157. val = "attachment; filename=";
  1158. CPPUNIT_ASSERT_EQUAL(
  1159. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1160. val.c_str(), val.size()));
  1161. // zero-length filename. quoted-string can be empty string, so this
  1162. // is ok.
  1163. val = "attachment; filename=\"\"";
  1164. CPPUNIT_ASSERT_EQUAL(
  1165. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1166. val.c_str(), val.size()));
  1167. // empty value is not allowed
  1168. val = "attachment; filename=;";
  1169. CPPUNIT_ASSERT_EQUAL(
  1170. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1171. val.c_str(), val.size()));
  1172. // / is not valid char in token.
  1173. val = "attachment; filename=dir/file";
  1174. CPPUNIT_ASSERT_EQUAL(
  1175. (ssize_t)-1, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1176. val.c_str(), val.size()));
  1177. // value-chars is *(pct-encoded / attr-char), so empty string is
  1178. // allowed.
  1179. val = "attachment; filename*=UTF-8''";
  1180. CPPUNIT_ASSERT_EQUAL(
  1181. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1182. val.c_str(), val.size()));
  1183. CPPUNIT_ASSERT_EQUAL(std::string("UTF-8"), std::string(cs, cslen));
  1184. val = "attachment; filename*=UTF-8''; filename=foo";
  1185. CPPUNIT_ASSERT_EQUAL(
  1186. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1187. val.c_str(), val.size()));
  1188. CPPUNIT_ASSERT_EQUAL(std::string("UTF-8"), std::string(cs, cslen));
  1189. val = "attachment; filename*=UTF-8'' ; filename=foo";
  1190. CPPUNIT_ASSERT_EQUAL(
  1191. (ssize_t)0, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1192. val.c_str(), val.size()));
  1193. CPPUNIT_ASSERT_EQUAL(std::string("UTF-8"), std::string(cs, cslen));
  1194. // with language
  1195. val = "attachment; filename*=UTF-8'japanese'konnichiwa";
  1196. CPPUNIT_ASSERT_EQUAL(
  1197. (ssize_t)10, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1198. val.c_str(), val.size()));
  1199. CPPUNIT_ASSERT_EQUAL(std::string("konnichiwa"),
  1200. std::string(&dest[0], &dest[10]));
  1201. // lws before and after "="
  1202. val = "attachment; filename = foo.html";
  1203. CPPUNIT_ASSERT_EQUAL(
  1204. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1205. val.c_str(), val.size()));
  1206. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1207. std::string(&dest[0], &dest[8]));
  1208. // lws before and after "=" with quoted-string
  1209. val = "attachment; filename = \"foo.html\"";
  1210. CPPUNIT_ASSERT_EQUAL(
  1211. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1212. val.c_str(), val.size()));
  1213. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1214. std::string(&dest[0], &dest[8]));
  1215. // lws after parm
  1216. val = "attachment; filename=foo.html ";
  1217. CPPUNIT_ASSERT_EQUAL(
  1218. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1219. val.c_str(), val.size()));
  1220. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1221. std::string(&dest[0], &dest[8]));
  1222. val = "attachment; filename=foo.html ; hello=world";
  1223. CPPUNIT_ASSERT_EQUAL(
  1224. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1225. val.c_str(), val.size()));
  1226. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1227. std::string(&dest[0], &dest[8]));
  1228. val = "attachment; filename=\"foo.html\" ";
  1229. CPPUNIT_ASSERT_EQUAL(
  1230. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1231. val.c_str(), val.size()));
  1232. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1233. std::string(&dest[0], &dest[8]));
  1234. val = "attachment; filename=\"foo.html\" ; hello=world";
  1235. CPPUNIT_ASSERT_EQUAL(
  1236. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1237. val.c_str(), val.size()));
  1238. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1239. std::string(&dest[0], &dest[8]));
  1240. val = "attachment; filename*=UTF-8''foo.html ; hello=world";
  1241. CPPUNIT_ASSERT_EQUAL(
  1242. (ssize_t)8, util::parse_content_disposition(dest, destlen, &cs, &cslen,
  1243. val.c_str(), val.size()));
  1244. CPPUNIT_ASSERT_EQUAL(std::string("foo.html"),
  1245. std::string(&dest[0], &dest[8]));
  1246. }
  1247. } // namespace aria2