test.cpp 86 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400
  1. /*
  2. * uriparser - RFC 3986 URI parsing library
  3. *
  4. * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
  5. * Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org>
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <uriparser/Uri.h>
  22. #include <uriparser/UriIp4.h>
  23. #include <gtest/gtest.h>
  24. #include <memory>
  25. #include <cstdio>
  26. #include <cstdlib>
  27. #include <cwchar>
  28. using namespace std;
  29. extern "C" {
  30. UriBool uri_TESTING_ONLY_ParseIpSixA(const char * text);
  31. UriBool uri_TESTING_ONLY_ParseIpFourA(const char * text);
  32. int uriCompareRangeA(const UriTextRangeA * a, const UriTextRangeA * b);
  33. }
  34. #define URI_TEST_IP_FOUR_FAIL(x) ASSERT_TRUE(URI_FALSE == uri_TESTING_ONLY_ParseIpFourA(x))
  35. #define URI_TEST_IP_FOUR_PASS(x) ASSERT_TRUE(URI_TRUE == uri_TESTING_ONLY_ParseIpFourA(x))
  36. // Note the closing brackets! TODO
  37. #define URI_TEST_IP_SIX_FAIL(x) ASSERT_TRUE(URI_FALSE == uri_TESTING_ONLY_ParseIpSixA(x "]"))
  38. #define URI_TEST_IP_SIX_PASS(x) ASSERT_TRUE(URI_TRUE == uri_TESTING_ONLY_ParseIpSixA(x "]"))
  39. #define URI_EXPECT_BETWEEN(candidate, first, afterLast) \
  40. EXPECT_TRUE((candidate >= first) && (candidate <= afterLast))
  41. #define URI_EXPECT_OUTSIDE(candidate, first, afterLast) \
  42. EXPECT_TRUE((candidate < first) || (candidate > afterLast))
  43. #define URI_EXPECT_RANGE_BETWEEN(range, uriFirst, uriAfterLast) \
  44. URI_EXPECT_BETWEEN(range.first, uriFirst, uriAfterLast); \
  45. URI_EXPECT_BETWEEN(range.afterLast, uriFirst, uriAfterLast)
  46. #define URI_EXPECT_RANGE_OUTSIDE(range, uriFirst, uriAfterLast) \
  47. URI_EXPECT_OUTSIDE(range.first, uriFirst, uriAfterLast); \
  48. URI_EXPECT_OUTSIDE(range.afterLast, uriFirst, uriAfterLast)
  49. #define URI_EXPECT_RANGE_EMPTY(range) \
  50. EXPECT_TRUE((range.first != NULL) \
  51. && (range.afterLast != NULL) \
  52. && (range.first == range.afterLast))
  53. namespace {
  54. bool testDistinctionHelper(const char * uriText, bool expectedHostSet,
  55. bool expectedAbsPath, bool expectedEmptyTailSegment) {
  56. UriParserStateA state;
  57. UriUriA uri;
  58. state.uri = &uri;
  59. int res = uriParseUriA(&state, uriText);
  60. if (res != URI_SUCCESS) {
  61. uriFreeUriMembersA(&uri);
  62. return false;
  63. }
  64. if (expectedHostSet != (uri.hostText.first != NULL)) {
  65. uriFreeUriMembersA(&uri);
  66. return false;
  67. }
  68. if (expectedAbsPath != (uri.absolutePath == URI_TRUE)) {
  69. uriFreeUriMembersA(&uri);
  70. return false;
  71. }
  72. if (expectedEmptyTailSegment != ((uri.pathTail != NULL)
  73. && (uri.pathTail->text.first == uri.pathTail->text.afterLast))) {
  74. uriFreeUriMembersA(&uri);
  75. return false;
  76. }
  77. uriFreeUriMembersA(&uri);
  78. return true;
  79. }
  80. } // namespace
  81. TEST(UriSuite, TestDistinction) {
  82. /*
  83. ============================================================================
  84. Rule | Example | hostSet | absPath | emptySeg
  85. ------------------------------------|---------|---------|---------|---------
  86. 1) URI = scheme ":" hier-part ... | | | |
  87. 1) "//" authority path-abempty | "s://" | true | false | false
  88. | "s:///" | true | false | true
  89. | "s://a" | true | false | false
  90. | "s://a/"| true | false | true
  91. 2) path-absolute | "s:/" | false | true | false
  92. 3) path-rootless | "s:a" | false | false | false
  93. | "s:a/" | false | false | true
  94. 4) path-empty | "s:" | false | false | false
  95. ------------------------------------|---------|---------|---------|---------
  96. 2) relative-ref = relative-part ... | | | |
  97. 1) "//" authority path-abempty | "//" | true | false | false
  98. | "///" | true | false | true
  99. 2) path-absolute | "/" | false | true | false
  100. 3) path-noscheme | "a" | false | false | false
  101. | "a/" | false | false | true
  102. 4) path-empty | "" | false | false | false
  103. ============================================================================
  104. */
  105. ASSERT_TRUE(testDistinctionHelper("s://", true, false, false));
  106. ASSERT_TRUE(testDistinctionHelper("s:///", true, false, true));
  107. ASSERT_TRUE(testDistinctionHelper("s://a", true, false, false));
  108. ASSERT_TRUE(testDistinctionHelper("s://a/", true, false, true));
  109. ASSERT_TRUE(testDistinctionHelper("s:/", false, true, false));
  110. ASSERT_TRUE(testDistinctionHelper("s:a", false, false, false));
  111. ASSERT_TRUE(testDistinctionHelper("s:a/", false, false, true));
  112. ASSERT_TRUE(testDistinctionHelper("s:", false, false, false));
  113. ASSERT_TRUE(testDistinctionHelper("//", true, false, false));
  114. ASSERT_TRUE(testDistinctionHelper("///", true, false, true));
  115. ASSERT_TRUE(testDistinctionHelper("/", false, true, false));
  116. ASSERT_TRUE(testDistinctionHelper("a", false, false, false));
  117. ASSERT_TRUE(testDistinctionHelper("a/", false, false, true));
  118. ASSERT_TRUE(testDistinctionHelper("", false, false, false));
  119. }
  120. TEST(UriSuite, TestIpFour) {
  121. URI_TEST_IP_FOUR_FAIL("01.0.0.0");
  122. URI_TEST_IP_FOUR_FAIL("001.0.0.0");
  123. URI_TEST_IP_FOUR_FAIL("00.0.0.0");
  124. URI_TEST_IP_FOUR_FAIL("000.0.0.0");
  125. URI_TEST_IP_FOUR_FAIL("256.0.0.0");
  126. URI_TEST_IP_FOUR_FAIL("300.0.0.0");
  127. URI_TEST_IP_FOUR_FAIL("1111.0.0.0");
  128. URI_TEST_IP_FOUR_FAIL("-1.0.0.0");
  129. URI_TEST_IP_FOUR_FAIL("0.0.0");
  130. URI_TEST_IP_FOUR_FAIL("0.0.0.");
  131. URI_TEST_IP_FOUR_FAIL("0.0.0.0.");
  132. URI_TEST_IP_FOUR_FAIL("0.0.0.0.0");
  133. URI_TEST_IP_FOUR_FAIL("0.0..0");
  134. URI_TEST_IP_FOUR_FAIL(".0.0.0");
  135. URI_TEST_IP_FOUR_PASS("255.0.0.0");
  136. URI_TEST_IP_FOUR_PASS("0.0.0.0");
  137. URI_TEST_IP_FOUR_PASS("1.0.0.0");
  138. URI_TEST_IP_FOUR_PASS("2.0.0.0");
  139. URI_TEST_IP_FOUR_PASS("3.0.0.0");
  140. URI_TEST_IP_FOUR_PASS("30.0.0.0");
  141. }
  142. TEST(UriSuite, TestIpSixPass) {
  143. // Quad length
  144. URI_TEST_IP_SIX_PASS("abcd::");
  145. URI_TEST_IP_SIX_PASS("abcd::1");
  146. URI_TEST_IP_SIX_PASS("abcd::12");
  147. URI_TEST_IP_SIX_PASS("abcd::123");
  148. URI_TEST_IP_SIX_PASS("abcd::1234");
  149. // Full length
  150. URI_TEST_IP_SIX_PASS("2001:0db8:0100:f101:0210:a4ff:fee3:9566"); // lower hex
  151. URI_TEST_IP_SIX_PASS("2001:0DB8:0100:F101:0210:A4FF:FEE3:9566"); // Upper hex
  152. URI_TEST_IP_SIX_PASS("2001:db8:100:f101:210:a4ff:fee3:9566");
  153. URI_TEST_IP_SIX_PASS("2001:0db8:100:f101:0:0:0:1");
  154. URI_TEST_IP_SIX_PASS("1:2:3:4:5:6:255.255.255.255");
  155. // Legal IPv4
  156. URI_TEST_IP_SIX_PASS("::1.2.3.4");
  157. URI_TEST_IP_SIX_PASS("3:4::5:1.2.3.4");
  158. URI_TEST_IP_SIX_PASS("::ffff:1.2.3.4");
  159. URI_TEST_IP_SIX_PASS("::0.0.0.0"); // Min IPv4
  160. URI_TEST_IP_SIX_PASS("::255.255.255.255"); // Max IPv4
  161. // Zipper position
  162. URI_TEST_IP_SIX_PASS("::1:2:3:4:5:6:7");
  163. URI_TEST_IP_SIX_PASS("1::1:2:3:4:5:6");
  164. URI_TEST_IP_SIX_PASS("1:2::1:2:3:4:5");
  165. URI_TEST_IP_SIX_PASS("1:2:3::1:2:3:4");
  166. URI_TEST_IP_SIX_PASS("1:2:3:4::1:2:3");
  167. URI_TEST_IP_SIX_PASS("1:2:3:4:5::1:2");
  168. URI_TEST_IP_SIX_PASS("1:2:3:4:5:6::1");
  169. URI_TEST_IP_SIX_PASS("1:2:3:4:5:6:7::");
  170. // Zipper length
  171. URI_TEST_IP_SIX_PASS("1:1:1::1:1:1:1");
  172. URI_TEST_IP_SIX_PASS("1:1:1::1:1:1");
  173. URI_TEST_IP_SIX_PASS("1:1:1::1:1");
  174. URI_TEST_IP_SIX_PASS("1:1::1:1");
  175. URI_TEST_IP_SIX_PASS("1:1::1");
  176. URI_TEST_IP_SIX_PASS("1::1");
  177. URI_TEST_IP_SIX_PASS("::1"); // == localhost
  178. URI_TEST_IP_SIX_PASS("::"); // == all addresses
  179. // A few more variations
  180. URI_TEST_IP_SIX_PASS("21ff:abcd::1");
  181. URI_TEST_IP_SIX_PASS("2001:db8:100:f101::1");
  182. URI_TEST_IP_SIX_PASS("a:b:c::12:1");
  183. URI_TEST_IP_SIX_PASS("a:b::0:1:2:3");
  184. // Issue #146: These are not leading zeros.
  185. URI_TEST_IP_SIX_PASS("::100.1.1.1");
  186. URI_TEST_IP_SIX_PASS("::1.100.1.1");
  187. URI_TEST_IP_SIX_PASS("::1.1.100.1");
  188. URI_TEST_IP_SIX_PASS("::1.1.1.100");
  189. URI_TEST_IP_SIX_PASS("::100.100.100.100");
  190. URI_TEST_IP_SIX_PASS("::10.1.1.1");
  191. URI_TEST_IP_SIX_PASS("::1.10.1.1");
  192. URI_TEST_IP_SIX_PASS("::1.1.10.1");
  193. URI_TEST_IP_SIX_PASS("::1.1.1.10");
  194. URI_TEST_IP_SIX_PASS("::10.10.10.10");
  195. }
  196. TEST(UriSuite, TestIpSixFail) {
  197. // 5 char quad
  198. URI_TEST_IP_SIX_FAIL("::12345");
  199. // Two zippers
  200. URI_TEST_IP_SIX_FAIL("abcd::abcd::abcd");
  201. // Triple-colon zipper
  202. URI_TEST_IP_SIX_FAIL(":::1234");
  203. URI_TEST_IP_SIX_FAIL("1234:::1234:1234");
  204. URI_TEST_IP_SIX_FAIL("1234:1234:::1234");
  205. URI_TEST_IP_SIX_FAIL("1234:::");
  206. // No quads, just IPv4
  207. URI_TEST_IP_SIX_FAIL("1.2.3.4");
  208. URI_TEST_IP_SIX_FAIL("0001.0002.0003.0004");
  209. // Five quads
  210. URI_TEST_IP_SIX_FAIL("0000:0000:0000:0000:0000:1.2.3.4");
  211. // Seven quads
  212. URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0");
  213. URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:");
  214. URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:1.2.3.4");
  215. // Nine quads (or more)
  216. URI_TEST_IP_SIX_FAIL("1:2:3:4:5:6:7:8:9");
  217. URI_TEST_IP_SIX_FAIL("::2:3:4:5:6:7:8:9");
  218. URI_TEST_IP_SIX_FAIL("1:2:3:4::6:7:8:9");
  219. URI_TEST_IP_SIX_FAIL("1:2:3:4:5:6:7:8::");
  220. // Invalid IPv4 part
  221. URI_TEST_IP_SIX_FAIL("::ffff:001.02.03.004"); // Leading zeros
  222. URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.1111"); // Four char octet
  223. URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.256"); // > 255
  224. URI_TEST_IP_SIX_FAIL("::ffff:311.2.3.4"); // > 155
  225. URI_TEST_IP_SIX_FAIL("::ffff:1.2.3:4"); // Not a dot
  226. URI_TEST_IP_SIX_FAIL("::ffff:1.2.3"); // Missing octet
  227. URI_TEST_IP_SIX_FAIL("::ffff:1.2.3."); // Missing octet
  228. URI_TEST_IP_SIX_FAIL("::ffff:1.2.3a.4"); // Hex in octet
  229. URI_TEST_IP_SIX_FAIL("::ffff:1.2.3.4:123"); // Crap input
  230. // Nonhex
  231. URI_TEST_IP_SIX_FAIL("g:0:0:0:0:0:0");
  232. // Issue #146: Zipper between the 7th and 8th quads.
  233. URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0::1");
  234. // Issue #146: Leading or trailing ":".
  235. URI_TEST_IP_SIX_FAIL(":1::1");
  236. URI_TEST_IP_SIX_FAIL("1::1:");
  237. URI_TEST_IP_SIX_FAIL(":1::1:");
  238. URI_TEST_IP_SIX_FAIL(":0:0:0:0:0:0:0:0");
  239. URI_TEST_IP_SIX_FAIL("0:0:0:0:0:0:0:0:");
  240. URI_TEST_IP_SIX_FAIL(":0:0:0:0:0:0:0:0:");
  241. // Issue #146: Zipper between six quads and IPv4 address.
  242. URI_TEST_IP_SIX_FAIL("1:1:1:1:1:1::1.1.1.1");
  243. }
  244. TEST(UriSuite, TestIpFuture) {
  245. UriParserStateA stateA;
  246. UriUriA uriA;
  247. stateA.uri = &uriA;
  248. // Issue #146: The leading "v" of IPvFuture is case-insensitive.
  249. ASSERT_TRUE(0 == uriParseUriA(&stateA, "//[vF.addr]"));
  250. uriFreeUriMembersA(&uriA);
  251. ASSERT_TRUE(0 == uriParseUriA(&stateA, "//[VF.addr]"));
  252. uriFreeUriMembersA(&uriA);
  253. }
  254. TEST(UriSuite, TestIpSixOverread) {
  255. UriUriA uri;
  256. const char * errorPos;
  257. // NOTE: This string is designed to not have a terminator
  258. char uriText[2 + 3 + 2 + 1 + 1];
  259. memcpy(uriText, "//[::44.1", sizeof(uriText));
  260. EXPECT_EQ(uriParseSingleUriExA(&uri, uriText,
  261. uriText + sizeof(uriText), &errorPos), URI_ERROR_SYNTAX);
  262. EXPECT_EQ(errorPos, uriText + sizeof(uriText));
  263. }
  264. TEST(UriSuite, TestUri) {
  265. UriParserStateA stateA;
  266. UriParserStateW stateW;
  267. UriUriA uriA;
  268. UriUriW uriW;
  269. stateA.uri = &uriA;
  270. stateW.uri = &uriW;
  271. // On/off for each
  272. ASSERT_TRUE(0 == uriParseUriA(&stateA, "//user:pass@[::1]:80/segment/index.html?query#frag"));
  273. uriFreeUriMembersA(&uriA);
  274. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://[::1]:80/segment/index.html?query#frag"));
  275. uriFreeUriMembersA(&uriA);
  276. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]/segment/index.html?query#frag"));
  277. uriFreeUriMembersA(&uriA);
  278. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80?query#frag"));
  279. uriFreeUriMembersA(&uriA);
  280. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80/segment/index.html#frag"));
  281. uriFreeUriMembersA(&uriA);
  282. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://user:pass@[::1]:80/segment/index.html?query"));
  283. uriFreeUriMembersA(&uriA);
  284. // Schema, port, one segment
  285. ASSERT_TRUE(0 == uriParseUriA(&stateA, "ftp://host:21/gnu/"));
  286. uriFreeUriMembersA(&uriA);
  287. // Relative
  288. ASSERT_TRUE(0 == uriParseUriA(&stateA, "one/two/three"));
  289. ASSERT_TRUE(!uriA.absolutePath);
  290. uriFreeUriMembersA(&uriA);
  291. ASSERT_TRUE(0 == uriParseUriA(&stateA, "/one/two/three"));
  292. ASSERT_TRUE(uriA.absolutePath);
  293. uriFreeUriMembersA(&uriA);
  294. ASSERT_TRUE(0 == uriParseUriA(&stateA, "//user:pass@localhost/one/two/three"));
  295. uriFreeUriMembersA(&uriA);
  296. // Both narrow and wide string version
  297. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://www.example.com/"));
  298. uriFreeUriMembersA(&uriA);
  299. ASSERT_TRUE(0 == uriParseUriW(&stateW, L"http://www.example.com/"));
  300. uriFreeUriMembersW(&uriW);
  301. // Real life examples
  302. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://sourceforge.net/projects/uriparser/"));
  303. uriFreeUriMembersA(&uriA);
  304. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://sourceforge.net/project/platformdownload.php?group_id=182840"));
  305. uriFreeUriMembersA(&uriA);
  306. ASSERT_TRUE(0 == uriParseUriA(&stateA, "mailto:test@example.com"));
  307. uriFreeUriMembersA(&uriA);
  308. ASSERT_TRUE(0 == uriParseUriA(&stateA, "../../"));
  309. uriFreeUriMembersA(&uriA);
  310. ASSERT_TRUE(0 == uriParseUriA(&stateA, "/"));
  311. ASSERT_TRUE(uriA.absolutePath);
  312. uriFreeUriMembersA(&uriA);
  313. ASSERT_TRUE(0 == uriParseUriA(&stateA, ""));
  314. ASSERT_TRUE(!uriA.absolutePath);
  315. uriFreeUriMembersA(&uriA);
  316. ASSERT_TRUE(0 == uriParseUriA(&stateA, "file:///bin/bash"));
  317. uriFreeUriMembersA(&uriA);
  318. // Percent encoding
  319. ASSERT_TRUE(0 == uriParseUriA(&stateA, "http://www.example.com/name%20with%20spaces/"));
  320. uriFreeUriMembersA(&uriA);
  321. ASSERT_TRUE(0 != uriParseUriA(&stateA, "http://www.example.com/name with spaces/"));
  322. uriFreeUriMembersA(&uriA);
  323. }
  324. TEST(UriSuite, TestUriComponents) {
  325. UriParserStateA stateA;
  326. UriUriA uriA;
  327. stateA.uri = &uriA;
  328. // 0 4 0 3 0 15 01 0 7 01
  329. const char * const input = "http" "://" "sourceforge.net" "/" "project" "/"
  330. // 0 20 01 0 15
  331. "platformdownload.php" "?" "group_id=182840";
  332. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  333. ASSERT_TRUE(uriA.scheme.first == input);
  334. ASSERT_TRUE(uriA.scheme.afterLast == input + 4);
  335. ASSERT_TRUE(uriA.userInfo.first == NULL);
  336. ASSERT_TRUE(uriA.userInfo.afterLast == NULL);
  337. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3);
  338. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 15);
  339. ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL);
  340. ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL);
  341. ASSERT_TRUE(uriA.portText.first == NULL);
  342. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  343. ASSERT_TRUE(uriA.pathHead->text.first == input + 4 + 3 + 15 + 1);
  344. ASSERT_TRUE(uriA.pathHead->text.afterLast == input + 4 + 3 + 15 + 1 + 7);
  345. ASSERT_TRUE(uriA.pathHead->next->text.first == input + 4 + 3 + 15 + 1 + 7 + 1);
  346. ASSERT_TRUE(uriA.pathHead->next->text.afterLast == input + 4 + 3 + 15 + 1 + 7 + 1 + 20);
  347. ASSERT_TRUE(uriA.pathHead->next->next == NULL);
  348. ASSERT_TRUE(uriA.pathTail == uriA.pathHead->next);
  349. ASSERT_TRUE(uriA.query.first == input + 4 + 3 + 15 + 1 + 7 + 1 + 20 + 1);
  350. ASSERT_TRUE(uriA.query.afterLast == input + 4 + 3 + 15 + 1 + 7 + 1 + 20 + 1 + 15);
  351. ASSERT_TRUE(uriA.fragment.first == NULL);
  352. ASSERT_TRUE(uriA.fragment.afterLast == NULL);
  353. uriFreeUriMembersA(&uriA);
  354. }
  355. TEST(UriSuite, TestUriComponentsBug20070701) {
  356. UriParserStateA stateA;
  357. UriUriA uriA;
  358. stateA.uri = &uriA;
  359. // 01 01 01
  360. const char * const input = "a" ":" "b";
  361. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  362. ASSERT_TRUE(uriA.scheme.first == input);
  363. ASSERT_TRUE(uriA.scheme.afterLast == input + 1);
  364. ASSERT_TRUE(uriA.userInfo.first == NULL);
  365. ASSERT_TRUE(uriA.userInfo.afterLast == NULL);
  366. ASSERT_TRUE(uriA.hostText.first == NULL);
  367. ASSERT_TRUE(uriA.hostText.afterLast == NULL);
  368. ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL);
  369. ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL);
  370. ASSERT_TRUE(uriA.portText.first == NULL);
  371. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  372. ASSERT_TRUE(uriA.pathHead->text.first == input + 1 + 1);
  373. ASSERT_TRUE(uriA.pathHead->text.afterLast == input + 1 + 1 + 1);
  374. ASSERT_TRUE(uriA.pathHead->next == NULL);
  375. ASSERT_TRUE(uriA.pathTail == uriA.pathHead);
  376. ASSERT_TRUE(uriA.query.first == NULL);
  377. ASSERT_TRUE(uriA.query.afterLast == NULL);
  378. ASSERT_TRUE(uriA.fragment.first == NULL);
  379. ASSERT_TRUE(uriA.fragment.afterLast == NULL);
  380. ASSERT_TRUE(!uriA.absolutePath);
  381. uriFreeUriMembersA(&uriA);
  382. }
  383. TEST(UriSuite, TestUriUserInfoHostPort1) {
  384. // User info with ":", no port
  385. UriParserStateA stateA;
  386. UriUriA uriA;
  387. stateA.uri = &uriA;
  388. // 0 4 0 3 0 7 01 0 9
  389. const char * const input = "http" "://" "abc:def" "@" "localhost";
  390. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  391. ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3);
  392. ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7);
  393. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1);
  394. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
  395. ASSERT_TRUE(uriA.portText.first == NULL);
  396. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  397. uriFreeUriMembersA(&uriA);
  398. }
  399. TEST(UriSuite, TestUriUserInfoHostPort2) {
  400. // User info with ":", with port
  401. UriParserStateA stateA;
  402. UriUriA uriA;
  403. stateA.uri = &uriA;
  404. // 0 4 0 3 0 7 01 0 9
  405. const char * const input = "http" "://" "abc:def" "@" "localhost"
  406. // 01 0 3
  407. ":" "123";
  408. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  409. ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3);
  410. ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7);
  411. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1);
  412. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
  413. ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 7 + 1 + 9 + 1);
  414. ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 7 + 1 + 9 + 1 + 3);
  415. uriFreeUriMembersA(&uriA);
  416. }
  417. TEST(UriSuite, TestUriUserInfoHostPort22Bug1948038) {
  418. UriParserStateA stateA;
  419. UriUriA uriA;
  420. stateA.uri = &uriA;
  421. int res;
  422. res = uriParseUriA(&stateA, "http://user:21@host/");
  423. ASSERT_TRUE(URI_SUCCESS == res);
  424. ASSERT_TRUE(!memcmp(uriA.userInfo.first, "user:21", 7 * sizeof(char)));
  425. ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 7);
  426. ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
  427. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4);
  428. ASSERT_TRUE(uriA.portText.first == NULL);
  429. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  430. uriFreeUriMembersA(&uriA);
  431. res = uriParseUriA(&stateA, "http://user:1234@192.168.0.1:1234/foo.com");
  432. ASSERT_TRUE(URI_SUCCESS == res);
  433. uriFreeUriMembersA(&uriA);
  434. res = uriParseUriA(&stateA, "http://moo:21@moo:21@moo/");
  435. ASSERT_TRUE(URI_ERROR_SYNTAX == res);
  436. uriFreeUriMembersA(&uriA);
  437. res = uriParseUriA(&stateA, "http://moo:21@moo:21@moo:21/");
  438. ASSERT_TRUE(URI_ERROR_SYNTAX == res);
  439. uriFreeUriMembersA(&uriA);
  440. }
  441. TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198One) {
  442. // User info with ":", with port, with escaped chars in password
  443. UriParserStateA stateA;
  444. UriUriA uriA;
  445. stateA.uri = &uriA;
  446. int res;
  447. // 0 4 0 3 0 10 01 0 4 01
  448. res = uriParseUriA(&stateA, "http" "://" "user:%2F21" "@" "host" "/");
  449. ASSERT_TRUE(URI_SUCCESS == res);
  450. ASSERT_TRUE(!memcmp(uriA.userInfo.first, "user:%2F21", 10 * sizeof(char)));
  451. ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 10);
  452. ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
  453. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4);
  454. ASSERT_TRUE(uriA.portText.first == NULL);
  455. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  456. uriFreeUriMembersA(&uriA);
  457. }
  458. TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198Two) {
  459. // User info with ":", with port, with escaped chars in user name and password
  460. UriParserStateA stateA;
  461. UriUriA uriA;
  462. stateA.uri = &uriA;
  463. int res;
  464. // 0 4 0 3 0 13 01 0 4 01
  465. res = uriParseUriA(&stateA, "http" "://" "%2Fuser:%2F21" "@" "host" "/");
  466. ASSERT_TRUE(URI_SUCCESS == res);
  467. ASSERT_TRUE(!memcmp(uriA.userInfo.first, "%2Fuser:%2F21", 13 * sizeof(char)));
  468. ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 13);
  469. ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
  470. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4);
  471. ASSERT_TRUE(uriA.portText.first == NULL);
  472. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  473. uriFreeUriMembersA(&uriA);
  474. }
  475. TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198Three) {
  476. // User info with ":", with port, with escaped chars in password
  477. UriParserStateA stateA;
  478. UriUriA uriA;
  479. stateA.uri = &uriA;
  480. int res;
  481. // 0 4 0 3 0 16 01 0 4 01
  482. res = uriParseUriA(&stateA, "http" "://" "user:!$&'()*+,;=" "@" "host" "/");
  483. ASSERT_TRUE(URI_SUCCESS == res);
  484. ASSERT_TRUE(!memcmp(uriA.userInfo.first, "user:!$&'()*+,;=", 16 * sizeof(char)));
  485. ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 16);
  486. ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
  487. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4);
  488. ASSERT_TRUE(uriA.portText.first == NULL);
  489. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  490. uriFreeUriMembersA(&uriA);
  491. }
  492. TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198Four) {
  493. // User info with ":", with port, with escaped chars in user name and password
  494. UriParserStateA stateA;
  495. UriUriA uriA;
  496. stateA.uri = &uriA;
  497. int res;
  498. // 0 4 0 3 0 20 01 0 4 01
  499. res = uriParseUriA(&stateA, "http" "://" "!$&'()*+,;=:password" "@" "host" "/");
  500. ASSERT_TRUE(URI_SUCCESS == res);
  501. ASSERT_TRUE(!memcmp(uriA.userInfo.first, "!$&'()*+,;=:password", 20 * sizeof(char)));
  502. ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 20);
  503. ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
  504. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4);
  505. ASSERT_TRUE(uriA.portText.first == NULL);
  506. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  507. uriFreeUriMembersA(&uriA);
  508. }
  509. TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198RelatedOne) {
  510. // Empty user info
  511. UriParserStateA stateA;
  512. UriUriA uriA;
  513. stateA.uri = &uriA;
  514. int res;
  515. // 0 4 0 3 01 0 4 01
  516. res = uriParseUriA(&stateA, "http" "://" "@" "host" "/");
  517. ASSERT_TRUE(URI_SUCCESS == res);
  518. ASSERT_TRUE(uriA.userInfo.afterLast != NULL);
  519. ASSERT_TRUE(uriA.userInfo.first != NULL);
  520. ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 0);
  521. ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
  522. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4);
  523. ASSERT_TRUE(uriA.portText.first == NULL);
  524. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  525. uriFreeUriMembersA(&uriA);
  526. }
  527. TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198RelatedOneTwo) {
  528. // Empty user info
  529. UriParserStateA stateA;
  530. UriUriA uriA;
  531. stateA.uri = &uriA;
  532. int res;
  533. // 0 4 0 3 0 7 01
  534. res = uriParseUriA(&stateA, "http" "://" "%2Fhost" "/");
  535. ASSERT_TRUE(URI_SUCCESS == res);
  536. ASSERT_TRUE(uriA.userInfo.afterLast == NULL);
  537. ASSERT_TRUE(uriA.userInfo.first == NULL);
  538. ASSERT_TRUE(!memcmp(uriA.hostText.first, "%2Fhost", 7 * sizeof(char)));
  539. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 7);
  540. ASSERT_TRUE(uriA.portText.first == NULL);
  541. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  542. uriFreeUriMembersA(&uriA);
  543. }
  544. TEST(UriSuite, TestUriUserInfoHostPort23Bug3510198RelatedTwo) {
  545. // Several colons in userinfo
  546. UriParserStateA stateA;
  547. UriUriA uriA;
  548. stateA.uri = &uriA;
  549. int res;
  550. // 0 4 0 3 0 2 01 0 4 01
  551. res = uriParseUriA(&stateA, "http" "://" "::" "@" "host" "/");
  552. ASSERT_TRUE(URI_SUCCESS == res);
  553. ASSERT_TRUE(!memcmp(uriA.userInfo.first, "::", 2 * sizeof(char)));
  554. ASSERT_TRUE(uriA.userInfo.afterLast - uriA.userInfo.first == 2);
  555. ASSERT_TRUE(!memcmp(uriA.hostText.first, "host", 4 * sizeof(char)));
  556. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 4);
  557. ASSERT_TRUE(uriA.portText.first == NULL);
  558. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  559. uriFreeUriMembersA(&uriA);
  560. }
  561. TEST(UriSuite, TestUriUserInfoHostPort3) {
  562. // User info without ":", no port
  563. UriParserStateA stateA;
  564. UriUriA uriA;
  565. stateA.uri = &uriA;
  566. // 0 4 0 3 0 7 01 0 9
  567. const char * const input = "http" "://" "abcdefg" "@" "localhost";
  568. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  569. ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3);
  570. ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7);
  571. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1);
  572. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
  573. ASSERT_TRUE(uriA.portText.first == NULL);
  574. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  575. uriFreeUriMembersA(&uriA);
  576. }
  577. TEST(UriSuite, TestUriUserInfoHostPort4) {
  578. // User info without ":", with port
  579. UriParserStateA stateA;
  580. UriUriA uriA;
  581. stateA.uri = &uriA;
  582. // 0 4 0 3 0 7 01 0 9
  583. const char * const input = "http" "://" "abcdefg" "@" "localhost"
  584. // 01 0 3
  585. ":" "123";
  586. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  587. ASSERT_TRUE(uriA.userInfo.first == input + 4 + 3);
  588. ASSERT_TRUE(uriA.userInfo.afterLast == input + 4 + 3 + 7);
  589. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 7 + 1);
  590. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7 + 1 + 9);
  591. ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 7 + 1 + 9 + 1);
  592. ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 7 + 1 + 9 + 1 + 3);
  593. uriFreeUriMembersA(&uriA);
  594. }
  595. TEST(UriSuite, TestUriUserInfoHostPort5) {
  596. // No user info, no port
  597. UriParserStateA stateA;
  598. UriUriA uriA;
  599. stateA.uri = &uriA;
  600. // 0 4 0 3 0 9
  601. const char * const input = "http" "://" "localhost";
  602. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  603. ASSERT_TRUE(uriA.userInfo.first == NULL);
  604. ASSERT_TRUE(uriA.userInfo.afterLast == NULL);
  605. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3);
  606. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 9);
  607. ASSERT_TRUE(uriA.portText.first == NULL);
  608. ASSERT_TRUE(uriA.portText.afterLast == NULL);
  609. uriFreeUriMembersA(&uriA);
  610. }
  611. TEST(UriSuite, TestUriUserInfoHostPort6) {
  612. // No user info, with port
  613. UriParserStateA stateA;
  614. UriUriA uriA;
  615. stateA.uri = &uriA;
  616. // 0 4 0 3 0 9 01 0 3
  617. const char * const input = "http" "://" "localhost" ":" "123";
  618. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  619. ASSERT_TRUE(uriA.userInfo.first == NULL);
  620. ASSERT_TRUE(uriA.userInfo.afterLast == NULL);
  621. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3);
  622. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 9);
  623. ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 9 + 1);
  624. ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 9 + 1 + 3);
  625. uriFreeUriMembersA(&uriA);
  626. }
  627. TEST(UriSuite, TestUriHostRegname) {
  628. UriParserStateA stateA;
  629. UriUriA uriA;
  630. stateA.uri = &uriA;
  631. // 0 4 0 3 0 11
  632. const char * const input = "http" "://" "example.com";
  633. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  634. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3);
  635. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 11);
  636. ASSERT_TRUE(uriA.hostData.ip4 == NULL);
  637. ASSERT_TRUE(uriA.hostData.ip6 == NULL);
  638. ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL);
  639. ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL);
  640. uriFreeUriMembersA(&uriA);
  641. }
  642. TEST(UriSuite, TestUriHostIpFour1) {
  643. UriParserStateA stateA;
  644. UriUriA uriA;
  645. stateA.uri = &uriA;
  646. // 0 4 0 3 0 7 01 0 2
  647. const char * const input = "http" "://" "1.2.3.4" ":" "80";
  648. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  649. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3);
  650. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7);
  651. ASSERT_TRUE(uriA.hostData.ip4 != NULL);
  652. ASSERT_TRUE(uriA.hostData.ip6 == NULL);
  653. ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL);
  654. ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL);
  655. uriFreeUriMembersA(&uriA);
  656. }
  657. TEST(UriSuite, TestUriHostIpFour2) {
  658. UriParserStateA stateA;
  659. UriUriA uriA;
  660. stateA.uri = &uriA;
  661. // 0 4 0 3 0 7
  662. const char * const input = "http" "://" "1.2.3.4";
  663. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  664. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3);
  665. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 7);
  666. ASSERT_TRUE(uriA.hostData.ip4 != NULL);
  667. ASSERT_TRUE(uriA.hostData.ip6 == NULL);
  668. ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL);
  669. ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL);
  670. uriFreeUriMembersA(&uriA);
  671. }
  672. TEST(UriSuite, TestUriHostIpSix1) {
  673. UriParserStateA stateA;
  674. UriUriA uriA;
  675. stateA.uri = &uriA;
  676. // 0 4 0 3 01 45 01 0 2
  677. const char * const input = "http" "://" "[::1]" ":" "80";
  678. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  679. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 1);
  680. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 4);
  681. ASSERT_TRUE(uriA.hostData.ip4 == NULL);
  682. ASSERT_TRUE(uriA.hostData.ip6 != NULL);
  683. ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL);
  684. ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL);
  685. uriFreeUriMembersA(&uriA);
  686. }
  687. TEST(UriSuite, TestUriHostIpSix2) {
  688. UriParserStateA stateA;
  689. UriUriA uriA;
  690. stateA.uri = &uriA;
  691. // 0 4 0 3 01 45
  692. const char * const input = "http" "://" "[::1]";
  693. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  694. ASSERT_TRUE(uriA.hostText.first == input + 4 + 3 + 1);
  695. ASSERT_TRUE(uriA.hostText.afterLast == input + 4 + 3 + 4);
  696. ASSERT_TRUE(uriA.hostData.ip4 == NULL);
  697. ASSERT_TRUE(uriA.hostData.ip6 != NULL);
  698. ASSERT_TRUE(uriA.hostData.ipFuture.first == NULL);
  699. ASSERT_TRUE(uriA.hostData.ipFuture.afterLast == NULL);
  700. uriFreeUriMembersA(&uriA);
  701. }
  702. TEST(UriSuite, TestUriHostEmpty) {
  703. UriParserStateA stateA;
  704. UriUriA uriA;
  705. stateA.uri = &uriA;
  706. // 0 4 0 3 01 0 3
  707. const char * const input = "http" "://" ":" "123";
  708. const int res = uriParseUriA(&stateA, input);
  709. ASSERT_TRUE(URI_SUCCESS == res);
  710. ASSERT_TRUE(uriA.userInfo.first == NULL);
  711. ASSERT_TRUE(uriA.userInfo.afterLast == NULL);
  712. ASSERT_TRUE(uriA.hostText.first != NULL);
  713. ASSERT_TRUE(uriA.hostText.afterLast != NULL);
  714. ASSERT_TRUE(uriA.hostText.afterLast - uriA.hostText.first == 0);
  715. ASSERT_TRUE(uriA.portText.first == input + 4 + 3 + 1);
  716. ASSERT_TRUE(uriA.portText.afterLast == input + 4 + 3 + 1 + 3);
  717. uriFreeUriMembersA(&uriA);
  718. }
  719. TEST(UriSuite, TestUriHostIpFuture) {
  720. // TODO
  721. }
  722. namespace {
  723. bool testEscapingHelper(const wchar_t * in, const wchar_t * expectedOut,
  724. bool spaceToPlus = false, bool normalizeBreaks = false) {
  725. wchar_t * const buffer = new wchar_t[(normalizeBreaks ? 6 : 3)
  726. * wcslen(in) + 1];
  727. if (uriEscapeW(in, buffer, spaceToPlus, normalizeBreaks)
  728. != buffer + wcslen(expectedOut)) {
  729. delete [] buffer;
  730. return false;
  731. }
  732. const bool equal = !wcscmp(buffer, expectedOut);
  733. delete [] buffer;
  734. return equal;
  735. }
  736. } // namespace
  737. TEST(UriSuite, TestEscaping) {
  738. const bool SPACE_TO_PLUS = true;
  739. const bool SPACE_TO_PERCENT = false;
  740. const bool KEEP_UNMODIFIED = false;
  741. const bool NORMALIZE = true;
  742. // '+' to ' '
  743. ASSERT_TRUE(testEscapingHelper(L"abc def", L"abc+def", SPACE_TO_PLUS));
  744. ASSERT_TRUE(testEscapingHelper(L"abc def", L"abc%20def", SPACE_TO_PERCENT));
  745. // Percent encoding
  746. ASSERT_TRUE(testEscapingHelper(L"\x00", L"\0"));
  747. ASSERT_TRUE(testEscapingHelper(L"\x01", L"%01"));
  748. ASSERT_TRUE(testEscapingHelper(L"\xff", L"%FF"));
  749. // Linebreak normalization
  750. ASSERT_TRUE(testEscapingHelper(L"\x0d", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  751. ASSERT_TRUE(testEscapingHelper(L"g\x0d", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  752. ASSERT_TRUE(testEscapingHelper(L"\x0dg", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
  753. ASSERT_TRUE(testEscapingHelper(L"\x0d", L"%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  754. ASSERT_TRUE(testEscapingHelper(L"g\x0d", L"g%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  755. ASSERT_TRUE(testEscapingHelper(L"\x0dg", L"%0Dg", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  756. ASSERT_TRUE(testEscapingHelper(L"\x0a", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  757. ASSERT_TRUE(testEscapingHelper(L"g\x0a", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  758. ASSERT_TRUE(testEscapingHelper(L"\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
  759. ASSERT_TRUE(testEscapingHelper(L"\x0a", L"%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  760. ASSERT_TRUE(testEscapingHelper(L"g\x0a", L"g%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  761. ASSERT_TRUE(testEscapingHelper(L"\x0ag", L"%0Ag", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  762. ASSERT_TRUE(testEscapingHelper(L"\x0d\x0a", L"%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  763. ASSERT_TRUE(testEscapingHelper(L"g\x0d\x0a", L"g%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  764. ASSERT_TRUE(testEscapingHelper(L"\x0d\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
  765. ASSERT_TRUE(testEscapingHelper(L"\x0d\x0a", L"%0D%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  766. ASSERT_TRUE(testEscapingHelper(L"g\x0d\x0a", L"g%0D%0A", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  767. ASSERT_TRUE(testEscapingHelper(L"\x0d\x0ag", L"%0D%0Ag", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  768. ASSERT_TRUE(testEscapingHelper(L"\x0a\x0d", L"%0D%0A%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  769. ASSERT_TRUE(testEscapingHelper(L"g\x0a\x0d", L"g%0D%0A%0D%0A", SPACE_TO_PLUS, NORMALIZE));
  770. ASSERT_TRUE(testEscapingHelper(L"\x0a\x0dg", L"%0D%0A%0D%0Ag", SPACE_TO_PLUS, NORMALIZE));
  771. ASSERT_TRUE(testEscapingHelper(L"\x0a\x0d", L"%0A%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  772. ASSERT_TRUE(testEscapingHelper(L"g\x0a\x0d", L"g%0A%0D", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  773. ASSERT_TRUE(testEscapingHelper(L"\x0a\x0dg", L"%0A%0Dg", SPACE_TO_PLUS, KEEP_UNMODIFIED));
  774. }
  775. namespace {
  776. bool testUnescapingHelper(const wchar_t * input, const wchar_t * output,
  777. bool plusToSpace = false, UriBreakConversion breakConversion = URI_BR_DONT_TOUCH) {
  778. wchar_t * working = new wchar_t[URI_STRLEN(input) + 1];
  779. wcscpy(working, input);
  780. const wchar_t * newTermZero = uriUnescapeInPlaceExW(working,
  781. plusToSpace ? URI_TRUE : URI_FALSE, breakConversion);
  782. const bool success = ((newTermZero == working + wcslen(output))
  783. && !wcscmp(working, output));
  784. delete[] working;
  785. return success;
  786. }
  787. } // namespace
  788. TEST(UriSuite, TestUnescaping) {
  789. const bool PLUS_TO_SPACE = true;
  790. const bool PLUS_DONT_TOUCH = false;
  791. // Proper
  792. ASSERT_TRUE(testUnescapingHelper(L"abc%20%41BC", L"abc ABC"));
  793. ASSERT_TRUE(testUnescapingHelper(L"%20", L" "));
  794. // Incomplete
  795. ASSERT_TRUE(testUnescapingHelper(L"%0", L"%0"));
  796. // Nonhex
  797. ASSERT_TRUE(testUnescapingHelper(L"%0g", L"%0g"));
  798. ASSERT_TRUE(testUnescapingHelper(L"%G0", L"%G0"));
  799. // No double decoding
  800. ASSERT_TRUE(testUnescapingHelper(L"%2520", L"%20"));
  801. // Decoding of '+'
  802. ASSERT_TRUE(testUnescapingHelper(L"abc+def", L"abc+def", PLUS_DONT_TOUCH));
  803. ASSERT_TRUE(testUnescapingHelper(L"abc+def", L"abc def", PLUS_TO_SPACE));
  804. // Line break conversion
  805. ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  806. ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  807. ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  808. ASSERT_TRUE(testUnescapingHelper(L"%0d", L"\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  809. ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  810. ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  811. ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  812. ASSERT_TRUE(testUnescapingHelper(L"%0d%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  813. ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  814. ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  815. ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  816. ASSERT_TRUE(testUnescapingHelper(L"%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  817. ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  818. ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  819. ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  820. ASSERT_TRUE(testUnescapingHelper(L"%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  821. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  822. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  823. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  824. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a", L"\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  825. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  826. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  827. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  828. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0a", L"\x0d\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  829. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  830. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  831. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  832. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d", L"\x0d\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  833. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  834. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  835. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  836. ASSERT_TRUE(testUnescapingHelper(L"%0d%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  837. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  838. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  839. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  840. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d", L"\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  841. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  842. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  843. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  844. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a", L"\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  845. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0a\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  846. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0d\x0a\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  847. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0d\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  848. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0d", L"\x0a\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  849. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0a\x0a\x0a", PLUS_DONT_TOUCH, URI_BR_TO_UNIX));
  850. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0d\x0a\x0d\x0a\x0d\x0a", PLUS_DONT_TOUCH, URI_BR_TO_WINDOWS));
  851. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0d\x0d\x0d", PLUS_DONT_TOUCH, URI_BR_TO_MAC));
  852. ASSERT_TRUE(testUnescapingHelper(L"%0a%0d%0a%0d", L"\x0a\x0d\x0a\x0d", PLUS_DONT_TOUCH, URI_BR_DONT_TOUCH));
  853. }
  854. namespace {
  855. bool testAddBaseHelper(const wchar_t * base, const wchar_t * rel, const wchar_t * expectedResult, bool backward_compatibility = false) {
  856. UriParserStateW stateW;
  857. // Base
  858. UriUriW baseUri;
  859. stateW.uri = &baseUri;
  860. int res = uriParseUriW(&stateW, base);
  861. if (res != 0) {
  862. uriFreeUriMembersW(&baseUri);
  863. return false;
  864. }
  865. // Rel
  866. UriUriW relUri;
  867. stateW.uri = &relUri;
  868. res = uriParseUriW(&stateW, rel);
  869. if (res != 0) {
  870. uriFreeUriMembersW(&baseUri);
  871. uriFreeUriMembersW(&relUri);
  872. return false;
  873. }
  874. // Expected result
  875. UriUriW expectedUri;
  876. stateW.uri = &expectedUri;
  877. res = uriParseUriW(&stateW, expectedResult);
  878. if (res != 0) {
  879. uriFreeUriMembersW(&baseUri);
  880. uriFreeUriMembersW(&relUri);
  881. uriFreeUriMembersW(&expectedUri);
  882. return false;
  883. }
  884. // Transform
  885. UriUriW transformedUri;
  886. if (backward_compatibility) {
  887. res = uriAddBaseUriExW(&transformedUri, &relUri, &baseUri, URI_RESOLVE_IDENTICAL_SCHEME_COMPAT);
  888. } else {
  889. res = uriAddBaseUriW(&transformedUri, &relUri, &baseUri);
  890. }
  891. if (res != 0) {
  892. uriFreeUriMembersW(&baseUri);
  893. uriFreeUriMembersW(&relUri);
  894. uriFreeUriMembersW(&expectedUri);
  895. uriFreeUriMembersW(&transformedUri);
  896. return false;
  897. }
  898. const bool equal = (URI_TRUE == uriEqualsUriW(&transformedUri, &expectedUri));
  899. if (!equal) {
  900. wchar_t transformedUriText[1024 * 8];
  901. wchar_t expectedUriText[1024 * 8];
  902. uriToStringW(transformedUriText, &transformedUri, 1024 * 8, NULL);
  903. uriToStringW(expectedUriText, &expectedUri, 1024 * 8, NULL);
  904. #ifdef HAVE_WPRINTF
  905. wprintf(L"\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", expectedUriText, transformedUriText);
  906. #endif
  907. }
  908. uriFreeUriMembersW(&baseUri);
  909. uriFreeUriMembersW(&relUri);
  910. uriFreeUriMembersW(&expectedUri);
  911. uriFreeUriMembersW(&transformedUri);
  912. return equal;
  913. }
  914. } // namespace
  915. TEST(UriSuite, TestTrailingSlash) {
  916. UriParserStateA stateA;
  917. UriUriA uriA;
  918. stateA.uri = &uriA;
  919. // 0 3 01
  920. const char * const input = "abc" "/";
  921. ASSERT_TRUE(0 == uriParseUriA(&stateA, input));
  922. ASSERT_TRUE(uriA.pathHead->text.first == input);
  923. ASSERT_TRUE(uriA.pathHead->text.afterLast == input + 3);
  924. ASSERT_TRUE(uriA.pathHead->next->text.first == uriA.pathHead->next->text.afterLast);
  925. ASSERT_TRUE(uriA.pathHead->next->next == NULL);
  926. ASSERT_TRUE(uriA.pathTail == uriA.pathHead->next);
  927. uriFreeUriMembersA(&uriA);
  928. }
  929. TEST(UriSuite, TestAddBase) {
  930. // 5.4.1. Normal Examples
  931. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g:h", L"g:h"));
  932. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g", L"http://a/b/c/g"));
  933. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./g", L"http://a/b/c/g"));
  934. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/", L"http://a/b/c/g/"));
  935. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/g", L"http://a/g"));
  936. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"//g", L"http://g"));
  937. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"?y", L"http://a/b/c/d;p?y"));
  938. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y", L"http://a/b/c/g?y"));
  939. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"#s", L"http://a/b/c/d;p?q#s"));
  940. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s", L"http://a/b/c/g#s"));
  941. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y#s", L"http://a/b/c/g?y#s"));
  942. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L";x", L"http://a/b/c/;x"));
  943. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x", L"http://a/b/c/g;x"));
  944. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x?y#s", L"http://a/b/c/g;x?y#s"));
  945. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"", L"http://a/b/c/d;p?q"));
  946. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L".", L"http://a/b/c/"));
  947. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./", L"http://a/b/c/"));
  948. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"..", L"http://a/b/"));
  949. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../", L"http://a/b/"));
  950. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../g", L"http://a/b/g"));
  951. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../..", L"http://a/"));
  952. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../", L"http://a/"));
  953. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../g", L"http://a/g"));
  954. // 5.4.2. Abnormal Examples
  955. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../g", L"http://a/g"));
  956. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../../g", L"http://a/g"));
  957. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/./g", L"http://a/g"));
  958. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/../g", L"http://a/g"));
  959. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g.", L"http://a/b/c/g."));
  960. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L".g", L"http://a/b/c/.g"));
  961. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g..", L"http://a/b/c/g.."));
  962. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"..g", L"http://a/b/c/..g"));
  963. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./../g", L"http://a/b/g"));
  964. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"./g/.", L"http://a/b/c/g/"));
  965. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/./h", L"http://a/b/c/g/h"));
  966. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g/../h", L"http://a/b/c/h"));
  967. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x=1/./y", L"http://a/b/c/g;x=1/y"));
  968. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g;x=1/../y", L"http://a/b/c/y"));
  969. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y/./x", L"http://a/b/c/g?y/./x"));
  970. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g?y/../x", L"http://a/b/c/g?y/../x"));
  971. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s/./x", L"http://a/b/c/g#s/./x"));
  972. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"g#s/../x", L"http://a/b/c/g#s/../x"));
  973. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g", L"http:g"));
  974. // Backward compatibility (feature request #4, RFC3986 5.4.2)
  975. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g", L"http:g", false));
  976. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g", L"http://a/b/c/g", true));
  977. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"http:g?q#f", L"http://a/b/c/g?q#f", true));
  978. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"other:g?q#f", L"other:g?q#f", true));
  979. // Bug related to absolutePath flag set despite presence of host
  980. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/", L"http://a/"));
  981. ASSERT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"/g/", L"http://a/g/"));
  982. // GitHub issue #92
  983. EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/../d;p?q", L"../..", L"http://a/"));
  984. EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/../d;p?q", L"../../", L"http://a/"));
  985. EXPECT_TRUE(testAddBaseHelper(L"http://a/b/../c/d;p?q", L"../..", L"http://a/"));
  986. EXPECT_TRUE(testAddBaseHelper(L"http://a/b/../c/d;p?q", L"../../", L"http://a/"));
  987. EXPECT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../..", L"http://a/"));
  988. EXPECT_TRUE(testAddBaseHelper(L"http://a/../b/c/d;p?q", L"../../", L"http://a/"));
  989. EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../..", L"http://a/"));
  990. EXPECT_TRUE(testAddBaseHelper(L"http://a/b/c/d;p?q", L"../../../", L"http://a/"));
  991. }
  992. namespace {
  993. bool testToStringHelper(const wchar_t * text) {
  994. // Parse
  995. UriParserStateW state;
  996. UriUriW uri;
  997. state.uri = &uri;
  998. int res = uriParseUriW(&state, text);
  999. if (res != 0) {
  1000. uriFreeUriMembersW(&uri);
  1001. return false;
  1002. }
  1003. // Back to string, _huge_ limit
  1004. wchar_t shouldbeTheSame[1024 * 8];
  1005. res = uriToStringW(shouldbeTheSame, &uri, 1024 * 8, NULL);
  1006. if (res != 0) {
  1007. uriFreeUriMembersW(&uri);
  1008. return false;
  1009. }
  1010. // Compare
  1011. bool equals = (0 == wcscmp(shouldbeTheSame, text));
  1012. if (!equals) {
  1013. #ifdef HAVE_WPRINTF
  1014. wprintf(L"\n\n\nExpected: \"%s\"\nReceived: \"%s\"\n\n\n", text, shouldbeTheSame);
  1015. #endif
  1016. }
  1017. // Back to string, _exact_ limit
  1018. const int len = static_cast<int>(wcslen(text));
  1019. int charsWritten;
  1020. res = uriToStringW(shouldbeTheSame, &uri, len + 1, &charsWritten);
  1021. if ((res != 0) || (charsWritten != len + 1)) {
  1022. uriFreeUriMembersW(&uri);
  1023. return false;
  1024. }
  1025. // Back to string, _too small_ limit
  1026. res = uriToStringW(shouldbeTheSame, &uri, len, &charsWritten);
  1027. if ((res == 0) || (charsWritten >= len + 1)) {
  1028. uriFreeUriMembersW(&uri);
  1029. return false;
  1030. }
  1031. uriFreeUriMembersW(&uri);
  1032. return equals;
  1033. }
  1034. } // namespace
  1035. TEST(UriSuite, TestToString) {
  1036. // Scheme
  1037. ASSERT_TRUE(testToStringHelper(L"ftp://localhost/"));
  1038. // UserInfo
  1039. ASSERT_TRUE(testToStringHelper(L"http://user:pass@localhost/"));
  1040. // IPv4
  1041. ASSERT_TRUE(testToStringHelper(L"http://123.0.1.255/"));
  1042. // IPv6
  1043. ASSERT_TRUE(testToStringHelper(L"http://[abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd]/"));
  1044. // IPvFuture
  1045. ASSERT_TRUE(testToStringHelper(L"http://[vA.123456]/"));
  1046. // Port
  1047. ASSERT_TRUE(testToStringHelper(L"http://example.com:123/"));
  1048. // Path
  1049. ASSERT_TRUE(testToStringHelper(L"http://example.com"));
  1050. ASSERT_TRUE(testToStringHelper(L"http://example.com/"));
  1051. ASSERT_TRUE(testToStringHelper(L"http://example.com/abc/"));
  1052. ASSERT_TRUE(testToStringHelper(L"http://example.com/abc/def"));
  1053. ASSERT_TRUE(testToStringHelper(L"http://example.com/abc/def/"));
  1054. ASSERT_TRUE(testToStringHelper(L"http://example.com//"));
  1055. ASSERT_TRUE(testToStringHelper(L"http://example.com/./.."));
  1056. // Query
  1057. ASSERT_TRUE(testToStringHelper(L"http://example.com/?abc"));
  1058. // Fragment
  1059. ASSERT_TRUE(testToStringHelper(L"http://example.com/#abc"));
  1060. ASSERT_TRUE(testToStringHelper(L"http://example.com/?def#abc"));
  1061. // Relative
  1062. ASSERT_TRUE(testToStringHelper(L"a"));
  1063. ASSERT_TRUE(testToStringHelper(L"a/"));
  1064. ASSERT_TRUE(testToStringHelper(L"/a"));
  1065. ASSERT_TRUE(testToStringHelper(L"/a/"));
  1066. ASSERT_TRUE(testToStringHelper(L"abc"));
  1067. ASSERT_TRUE(testToStringHelper(L"abc/"));
  1068. ASSERT_TRUE(testToStringHelper(L"/abc"));
  1069. ASSERT_TRUE(testToStringHelper(L"/abc/"));
  1070. ASSERT_TRUE(testToStringHelper(L"a/def"));
  1071. ASSERT_TRUE(testToStringHelper(L"a/def/"));
  1072. ASSERT_TRUE(testToStringHelper(L"/a/def"));
  1073. ASSERT_TRUE(testToStringHelper(L"/a/def/"));
  1074. ASSERT_TRUE(testToStringHelper(L"abc/def"));
  1075. ASSERT_TRUE(testToStringHelper(L"abc/def/"));
  1076. ASSERT_TRUE(testToStringHelper(L"/abc/def"));
  1077. ASSERT_TRUE(testToStringHelper(L"/abc/def/"));
  1078. ASSERT_TRUE(testToStringHelper(L"/"));
  1079. ASSERT_TRUE(testToStringHelper(L"//a/"));
  1080. ASSERT_TRUE(testToStringHelper(L"."));
  1081. ASSERT_TRUE(testToStringHelper(L"./"));
  1082. ASSERT_TRUE(testToStringHelper(L"/."));
  1083. ASSERT_TRUE(testToStringHelper(L"/./"));
  1084. ASSERT_TRUE(testToStringHelper(L""));
  1085. ASSERT_TRUE(testToStringHelper(L"./abc/def"));
  1086. ASSERT_TRUE(testToStringHelper(L"?query"));
  1087. ASSERT_TRUE(testToStringHelper(L"#fragment"));
  1088. ASSERT_TRUE(testToStringHelper(L"?query#fragment"));
  1089. // Tests for bugs from the past
  1090. ASSERT_TRUE(testToStringHelper(L"f:/.//g"));
  1091. }
  1092. TEST(UriSuite, TestToStringBug1950126) {
  1093. UriParserStateW state;
  1094. UriUriW uriOne;
  1095. UriUriW uriTwo;
  1096. const wchar_t * const uriOneString = L"http://e.com/";
  1097. const wchar_t * const uriTwoString = L"http://e.com";
  1098. state.uri = &uriOne;
  1099. ASSERT_TRUE(URI_SUCCESS == uriParseUriW(&state, uriOneString));
  1100. state.uri = &uriTwo;
  1101. ASSERT_TRUE(URI_SUCCESS == uriParseUriW(&state, uriTwoString));
  1102. ASSERT_TRUE(URI_FALSE == uriEqualsUriW(&uriOne, &uriTwo));
  1103. uriFreeUriMembersW(&uriOne);
  1104. uriFreeUriMembersW(&uriTwo);
  1105. ASSERT_TRUE(testToStringHelper(uriOneString));
  1106. ASSERT_TRUE(testToStringHelper(uriTwoString));
  1107. }
  1108. namespace {
  1109. bool testToStringCharsRequiredHelper(const wchar_t * text) {
  1110. // Parse
  1111. UriParserStateW state;
  1112. UriUriW uri;
  1113. state.uri = &uri;
  1114. int res = uriParseUriW(&state, text);
  1115. if (res != 0) {
  1116. uriFreeUriMembersW(&uri);
  1117. return false;
  1118. }
  1119. // Required space?
  1120. int charsRequired;
  1121. if (uriToStringCharsRequiredW(&uri, &charsRequired) != 0) {
  1122. uriFreeUriMembersW(&uri);
  1123. return false;
  1124. }
  1125. EXPECT_EQ(charsRequired, wcslen(text));
  1126. // Minimum
  1127. wchar_t * buffer = new wchar_t[charsRequired + 1];
  1128. if (uriToStringW(buffer, &uri, charsRequired + 1, NULL) != 0) {
  1129. uriFreeUriMembersW(&uri);
  1130. delete [] buffer;
  1131. return false;
  1132. }
  1133. // One less than minimum
  1134. if (uriToStringW(buffer, &uri, charsRequired, NULL) == 0) {
  1135. uriFreeUriMembersW(&uri);
  1136. delete [] buffer;
  1137. return false;
  1138. }
  1139. uriFreeUriMembersW(&uri);
  1140. delete [] buffer;
  1141. return true;
  1142. }
  1143. } // namespace
  1144. TEST(UriSuite, TestToStringCharsRequired) {
  1145. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.1.1/"));
  1146. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://12.1.1.1/"));
  1147. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://123.1.1.1/"));
  1148. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.12.1.1/"));
  1149. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.123.1.1/"));
  1150. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.12.1/"));
  1151. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.123.1/"));
  1152. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.1.12/"));
  1153. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://1.1.1.123/"));
  1154. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/"));
  1155. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com:80/"));
  1156. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://user:pass@www.example.com/"));
  1157. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/index.html"));
  1158. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/?abc"));
  1159. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/#def"));
  1160. EXPECT_TRUE(testToStringCharsRequiredHelper(L"http://www.example.com/?abc#def"));
  1161. EXPECT_TRUE(testToStringCharsRequiredHelper(L"/test"));
  1162. EXPECT_TRUE(testToStringCharsRequiredHelper(L"test"));
  1163. }
  1164. namespace {
  1165. bool testNormalizeMaskHelper(const wchar_t * uriText, unsigned int expectedMask) {
  1166. UriParserStateW state;
  1167. UriUriW uri;
  1168. state.uri = &uri;
  1169. int res = uriParseUriW(&state, uriText);
  1170. if (res != 0) {
  1171. uriFreeUriMembersW(&uri);
  1172. return false;
  1173. }
  1174. const unsigned int maskBefore = uriNormalizeSyntaxMaskRequiredW(&uri);
  1175. if (maskBefore != expectedMask) {
  1176. uriFreeUriMembersW(&uri);
  1177. return false;
  1178. }
  1179. res = uriNormalizeSyntaxW(&uri);
  1180. if (res != 0) {
  1181. uriFreeUriMembersW(&uri);
  1182. return false;
  1183. }
  1184. const unsigned int maskAfter = uriNormalizeSyntaxMaskRequiredW(&uri);
  1185. uriFreeUriMembersW(&uri);
  1186. // Second call should be no problem
  1187. uriFreeUriMembersW(&uri);
  1188. return (maskAfter == URI_NORMALIZED);
  1189. }
  1190. } // namespace
  1191. TEST(UriSuite, TestNormalizeSyntaxMaskRequired) {
  1192. ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/", URI_NORMALIZED));
  1193. ASSERT_TRUE(testNormalizeMaskHelper(L"httP://localhost/", URI_NORMALIZE_SCHEME));
  1194. ASSERT_TRUE(testNormalizeMaskHelper(L"http://%0d@localhost/", URI_NORMALIZE_USER_INFO));
  1195. ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhosT/", URI_NORMALIZE_HOST));
  1196. ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/./abc", URI_NORMALIZE_PATH));
  1197. ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/?AB%43", URI_NORMALIZE_QUERY));
  1198. ASSERT_TRUE(testNormalizeMaskHelper(L"http://localhost/#AB%43", URI_NORMALIZE_FRAGMENT));
  1199. }
  1200. namespace {
  1201. bool testNormalizeSyntaxHelper(const wchar_t * uriText, const wchar_t * expectedNormalized,
  1202. unsigned int mask = static_cast<unsigned int>(-1)) {
  1203. UriParserStateW stateW;
  1204. int res;
  1205. UriUriW testUri;
  1206. stateW.uri = &testUri;
  1207. res = uriParseUriW(&stateW, uriText);
  1208. if (res != 0) {
  1209. uriFreeUriMembersW(&testUri);
  1210. return false;
  1211. }
  1212. // Expected result
  1213. UriUriW expectedUri;
  1214. stateW.uri = &expectedUri;
  1215. res = uriParseUriW(&stateW, expectedNormalized);
  1216. if (res != 0) {
  1217. uriFreeUriMembersW(&testUri);
  1218. uriFreeUriMembersW(&expectedUri);
  1219. return false;
  1220. }
  1221. // First run
  1222. res = uriNormalizeSyntaxExW(&testUri, mask);
  1223. if (res != 0) {
  1224. uriFreeUriMembersW(&testUri);
  1225. uriFreeUriMembersW(&expectedUri);
  1226. return false;
  1227. }
  1228. bool equalAfter = (URI_TRUE == uriEqualsUriW(&testUri, &expectedUri));
  1229. // Second run
  1230. res = uriNormalizeSyntaxExW(&testUri, mask);
  1231. if (res != 0) {
  1232. uriFreeUriMembersW(&testUri);
  1233. uriFreeUriMembersW(&expectedUri);
  1234. return false;
  1235. }
  1236. equalAfter = equalAfter
  1237. && (URI_TRUE == uriEqualsUriW(&testUri, &expectedUri));
  1238. uriFreeUriMembersW(&testUri);
  1239. uriFreeUriMembersW(&expectedUri);
  1240. return equalAfter;
  1241. }
  1242. } // namespace
  1243. TEST(UriSuite, TestNormalizeSyntax) {
  1244. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1245. L"eXAMPLE://a/./b/../b/%63/%7bfoo%7d",
  1246. L"example://a/b/c/%7Bfoo%7D"));
  1247. // Testcase by Adrian Manrique
  1248. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1249. L"http://examp%4Ce.com/",
  1250. L"http://example.com/"));
  1251. // Testcase by Adrian Manrique
  1252. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1253. L"http://example.com/a/b/%2E%2E/",
  1254. L"http://example.com/a/"));
  1255. // Reported by Adrian Manrique
  1256. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1257. L"http://user:pass@SOMEHOST.COM:123",
  1258. L"http://user:pass@somehost.com:123"));
  1259. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1260. L"HTTP://a:b@HOST:123/./1/2/../%41?abc#def",
  1261. L"http://a:b@host:123/1/A?abc#def"));
  1262. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1263. L"../../abc",
  1264. L"../../abc"));
  1265. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1266. L"../../abc/..",
  1267. L"../../"));
  1268. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1269. L"../../abc/../def",
  1270. L"../../def"));
  1271. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1272. L"abc/..",
  1273. L""));
  1274. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1275. L"abc/../",
  1276. L""));
  1277. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1278. L"../../abc/./def",
  1279. L"../../abc/def"));
  1280. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1281. L"./def",
  1282. L"def"));
  1283. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1284. L"def/.",
  1285. L"def/"));
  1286. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1287. L"./abc:def",
  1288. L"./abc:def"));
  1289. }
  1290. TEST(UriSuite, TestNormalizeSyntaxComponents) {
  1291. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1292. L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
  1293. L"http://%41@EXAMPLE.ORG/../a?%41#%41",
  1294. URI_NORMALIZE_SCHEME));
  1295. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1296. L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
  1297. L"HTTP://A@EXAMPLE.ORG/../a?%41#%41",
  1298. URI_NORMALIZE_USER_INFO));
  1299. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1300. L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
  1301. L"HTTP://%41@example.org/../a?%41#%41",
  1302. URI_NORMALIZE_HOST));
  1303. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1304. L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
  1305. L"HTTP://%41@EXAMPLE.ORG/a?%41#%41",
  1306. URI_NORMALIZE_PATH));
  1307. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1308. L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
  1309. L"HTTP://%41@EXAMPLE.ORG/../a?A#%41",
  1310. URI_NORMALIZE_QUERY));
  1311. ASSERT_TRUE(testNormalizeSyntaxHelper(
  1312. L"HTTP://%41@EXAMPLE.ORG/../a?%41#%41",
  1313. L"HTTP://%41@EXAMPLE.ORG/../a?%41#A",
  1314. URI_NORMALIZE_FRAGMENT));
  1315. }
  1316. TEST(UriSuite, TestNormalizeSyntaxPath) {
  1317. // These are from GitHub issue #92
  1318. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1319. L"http://a/b/c/../../..",
  1320. L"http://a/",
  1321. URI_NORMALIZE_PATH));
  1322. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1323. L"http://a/b/../c/../..",
  1324. L"http://a/",
  1325. URI_NORMALIZE_PATH));
  1326. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1327. L"http://a/b/c/../../..",
  1328. L"http://a/",
  1329. URI_NORMALIZE_PATH));
  1330. // .. and these are related
  1331. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1332. L"http://a/..",
  1333. L"http://a/",
  1334. URI_NORMALIZE_PATH));
  1335. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1336. L"/..",
  1337. L"/",
  1338. URI_NORMALIZE_PATH));
  1339. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1340. L"http://a/..///",
  1341. L"http://a///",
  1342. URI_NORMALIZE_PATH));
  1343. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1344. L"http://a/..///..",
  1345. L"http://a//",
  1346. URI_NORMALIZE_PATH));
  1347. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1348. L"a/b/c/../../..",
  1349. L"",
  1350. URI_NORMALIZE_PATH));
  1351. EXPECT_TRUE(testNormalizeSyntaxHelper(
  1352. L"a/b/../../c/..",
  1353. L"",
  1354. URI_NORMALIZE_PATH));
  1355. }
  1356. TEST(UriSuite, TestNormalizeCrashBug20080224) {
  1357. UriParserStateW stateW;
  1358. int res;
  1359. UriUriW testUri;
  1360. stateW.uri = &testUri;
  1361. res = uriParseUriW(&stateW, L"http://example.org/abc//../def");
  1362. ASSERT_TRUE(res == 0);
  1363. // First call will make us owner of copied memory
  1364. res = uriNormalizeSyntaxExW(&testUri, URI_NORMALIZE_SCHEME);
  1365. ASSERT_TRUE(res == 0);
  1366. res = uriNormalizeSyntaxExW(&testUri, URI_NORMALIZE_HOST);
  1367. ASSERT_TRUE(res == 0);
  1368. // Frees empty path segment -> crash
  1369. res = uriNormalizeSyntaxW(&testUri);
  1370. ASSERT_TRUE(res == 0);
  1371. uriFreeUriMembersW(&testUri);
  1372. }
  1373. namespace {
  1374. void testFilenameUriConversionHelper(const wchar_t * filename,
  1375. const wchar_t * uriString, bool forUnix,
  1376. const wchar_t * expectedUriString = NULL) {
  1377. const int prefixLen = forUnix ? 7 : 8;
  1378. if (! expectedUriString) {
  1379. expectedUriString = uriString;
  1380. }
  1381. // Filename to URI string
  1382. const size_t uriBufferLen = prefixLen + 3 * wcslen(filename) + 1;
  1383. wchar_t * uriBuffer = new wchar_t[uriBufferLen];
  1384. if (forUnix) {
  1385. uriUnixFilenameToUriStringW(filename, uriBuffer);
  1386. } else {
  1387. uriWindowsFilenameToUriStringW(filename, uriBuffer);
  1388. }
  1389. #ifdef HAVE_WPRINTF
  1390. // wprintf(L"1 [%s][%s]\n", uriBuffer, expectedUriString);
  1391. #endif
  1392. ASSERT_TRUE(!wcscmp(uriBuffer, expectedUriString));
  1393. delete [] uriBuffer;
  1394. // URI string to filename
  1395. const size_t filenameBufferLen = wcslen(uriString) + 1;
  1396. wchar_t * filenameBuffer = new wchar_t[filenameBufferLen];
  1397. if (forUnix) {
  1398. uriUriStringToUnixFilenameW(uriString, filenameBuffer);
  1399. } else {
  1400. uriUriStringToWindowsFilenameW(uriString, filenameBuffer);
  1401. }
  1402. #ifdef HAVE_WPRINTF
  1403. // wprintf(L"2 [%s][%s]\n", filenameBuffer, filename);
  1404. #endif
  1405. ASSERT_TRUE(!wcscmp(filenameBuffer, filename));
  1406. delete [] filenameBuffer;
  1407. }
  1408. } // namespace
  1409. TEST(UriSuite, TestFilenameUriConversion) {
  1410. const bool FOR_UNIX = true;
  1411. const bool FOR_WINDOWS = false;
  1412. testFilenameUriConversionHelper(L"/bin/bash", L"file:///bin/bash", FOR_UNIX);
  1413. testFilenameUriConversionHelper(L"/bin/bash", L"file:/bin/bash", FOR_UNIX, L"file:///bin/bash");
  1414. testFilenameUriConversionHelper(L"./configure", L"./configure", FOR_UNIX);
  1415. testFilenameUriConversionHelper(L"E:\\Documents and Settings", L"file:///E:/Documents%20and%20Settings", FOR_WINDOWS);
  1416. testFilenameUriConversionHelper(L"c:\\path\\to\\file.txt", L"file:c:/path/to/file.txt", FOR_WINDOWS, L"file:///c:/path/to/file.txt");
  1417. testFilenameUriConversionHelper(L".\\Readme.txt", L"./Readme.txt", FOR_WINDOWS);
  1418. testFilenameUriConversionHelper(L"index.htm", L"index.htm", FOR_WINDOWS);
  1419. testFilenameUriConversionHelper(L"index.htm", L"index.htm", FOR_UNIX);
  1420. testFilenameUriConversionHelper(L"abc def", L"abc%20def", FOR_WINDOWS);
  1421. testFilenameUriConversionHelper(L"abc def", L"abc%20def", FOR_UNIX);
  1422. testFilenameUriConversionHelper(L"\\\\Server01\\user\\docs\\Letter.txt", L"file://Server01/user/docs/Letter.txt", FOR_WINDOWS);
  1423. }
  1424. TEST(UriSuite, TestCrashFreeUriMembersBug20080116) {
  1425. // Testcase by Adrian Manrique
  1426. UriParserStateA state;
  1427. UriUriA uri;
  1428. state.uri = &uri;
  1429. uriParseUriA(&state, "http://test/?");
  1430. uriNormalizeSyntaxA(&uri);
  1431. uriFreeUriMembersA(&uri);
  1432. ASSERT_TRUE(true);
  1433. }
  1434. namespace {
  1435. void helperTestQueryString(char const * uriString, int pairsExpected);
  1436. }
  1437. TEST(UriSuite, TestCrashReport2418192) {
  1438. // Testcase by Harvey Vrsalovic
  1439. helperTestQueryString("http://svcs.cnn.com/weather/wrapper.jsp?&csiID=csi1", 1);
  1440. }
  1441. TEST(UriSuite, TestPervertedQueryString) {
  1442. helperTestQueryString("http://example.org/?&&=&&&=&&&&==&===&====", 5);
  1443. }
  1444. TEST(UriSuite, TestQueryStringEndingInEqualSignNonBug32) {
  1445. const char * queryString = "firstname=sdsd&lastname=";
  1446. UriQueryListA * queryList = NULL;
  1447. int itemCount = 0;
  1448. const int res = uriDissectQueryMallocA(&queryList, &itemCount,
  1449. queryString, queryString + strlen(queryString));
  1450. ASSERT_TRUE(res == URI_SUCCESS);
  1451. ASSERT_TRUE(itemCount == 2);
  1452. ASSERT_TRUE(queryList != NULL);
  1453. ASSERT_TRUE(strcmp(queryList->key, "firstname") == 0);
  1454. ASSERT_TRUE(strcmp(queryList->value, "sdsd") == 0);
  1455. ASSERT_TRUE(strcmp(queryList->next->key, "lastname") == 0);
  1456. ASSERT_TRUE(strcmp(queryList->next->value, "") == 0);
  1457. ASSERT_TRUE(queryList->next->next == NULL);
  1458. uriFreeQueryListA(queryList);
  1459. }
  1460. namespace {
  1461. void helperTestQueryString(char const * uriString, int pairsExpected) {
  1462. UriParserStateA state;
  1463. UriUriA uri;
  1464. state.uri = &uri;
  1465. int res = uriParseUriA(&state, uriString);
  1466. ASSERT_TRUE(res == URI_SUCCESS);
  1467. UriQueryListA * queryList = NULL;
  1468. int itemCount = 0;
  1469. res = uriDissectQueryMallocA(&queryList, &itemCount,
  1470. uri.query.first, uri.query.afterLast);
  1471. ASSERT_TRUE(res == URI_SUCCESS);
  1472. ASSERT_TRUE(queryList != NULL);
  1473. ASSERT_TRUE(itemCount == pairsExpected);
  1474. uriFreeQueryListA(queryList);
  1475. uriFreeUriMembersA(&uri);
  1476. }
  1477. } // namespace
  1478. TEST(UriSuite, TestCrashMakeOwnerBug20080207) {
  1479. // Testcase by Adrian Manrique
  1480. UriParserStateA state;
  1481. UriUriA sourceUri;
  1482. state.uri = &sourceUri;
  1483. const char * const sourceUriString = "http://user:pass@somehost.com:80/";
  1484. if (uriParseUriA(&state, sourceUriString) != 0) {
  1485. ASSERT_TRUE(false);
  1486. }
  1487. if (uriNormalizeSyntaxA(&sourceUri) != 0) {
  1488. ASSERT_TRUE(false);
  1489. }
  1490. uriFreeUriMembersA(&sourceUri);
  1491. ASSERT_TRUE(true);
  1492. }
  1493. namespace {
  1494. void testQueryListHelper(const wchar_t * input, int expectedItemCount) {
  1495. int res;
  1496. UriBool spacePlusConversion = URI_TRUE;
  1497. UriBool normalizeBreaks = URI_FALSE;
  1498. UriBreakConversion breakConversion = URI_BR_DONT_TOUCH;
  1499. int itemCount;
  1500. UriQueryListW * queryList;
  1501. res = uriDissectQueryMallocExW(&queryList, &itemCount,
  1502. input, input + wcslen(input), spacePlusConversion, breakConversion);
  1503. ASSERT_TRUE(res == URI_SUCCESS);
  1504. ASSERT_TRUE(itemCount == expectedItemCount);
  1505. ASSERT_TRUE((queryList == NULL) == (expectedItemCount == 0));
  1506. if (expectedItemCount != 0) {
  1507. // First
  1508. int charsRequired;
  1509. res = uriComposeQueryCharsRequiredExW(queryList, &charsRequired, spacePlusConversion,
  1510. normalizeBreaks);
  1511. ASSERT_TRUE(res == URI_SUCCESS);
  1512. ASSERT_TRUE(charsRequired >= (int)wcslen(input));
  1513. wchar_t * recomposed = new wchar_t[charsRequired + 1];
  1514. int charsWritten;
  1515. res = uriComposeQueryExW(recomposed, queryList, charsRequired + 1,
  1516. &charsWritten, spacePlusConversion, normalizeBreaks);
  1517. ASSERT_TRUE(res == URI_SUCCESS);
  1518. ASSERT_TRUE(charsWritten <= charsRequired);
  1519. ASSERT_TRUE(charsWritten == (int)wcslen(input) + 1);
  1520. ASSERT_TRUE(!wcscmp(input, recomposed));
  1521. delete [] recomposed;
  1522. recomposed = NULL;
  1523. res = uriComposeQueryMallocW(&recomposed, queryList);
  1524. ASSERT_TRUE(res == URI_SUCCESS);
  1525. ASSERT_TRUE(recomposed != NULL);
  1526. ASSERT_TRUE(charsWritten == (int)wcslen(input) + 1);
  1527. ASSERT_TRUE(!wcscmp(input, recomposed));
  1528. free(recomposed);
  1529. }
  1530. uriFreeQueryListW(queryList);
  1531. }
  1532. } // namespace
  1533. TEST(UriSuite, QueryList) {
  1534. testQueryListHelper(L"one=ONE&two=TWO", 2);
  1535. testQueryListHelper(L"one=ONE&two=&three=THREE", 3);
  1536. testQueryListHelper(L"one=ONE&two&three=THREE", 3);
  1537. testQueryListHelper(L"one=ONE", 1);
  1538. testQueryListHelper(L"one", 1);
  1539. testQueryListHelper(L"", 0);
  1540. }
  1541. namespace {
  1542. void testQueryListPairHelper(const char * pair, const char * unescapedKey,
  1543. const char * unescapedValue, const char * fixed = NULL) {
  1544. int res;
  1545. UriQueryListA * queryList;
  1546. int itemCount;
  1547. res = uriDissectQueryMallocA(&queryList, &itemCount, pair, pair + strlen(pair));
  1548. ASSERT_TRUE(res == URI_SUCCESS);
  1549. ASSERT_TRUE(queryList != NULL);
  1550. ASSERT_TRUE(itemCount == 1);
  1551. ASSERT_TRUE(!strcmp(queryList->key, unescapedKey));
  1552. ASSERT_TRUE(!strcmp(queryList->value, unescapedValue));
  1553. char * recomposed;
  1554. res = uriComposeQueryMallocA(&recomposed, queryList);
  1555. ASSERT_TRUE(res == URI_SUCCESS);
  1556. ASSERT_TRUE(recomposed != NULL);
  1557. ASSERT_TRUE(!strcmp(recomposed, (fixed != NULL) ? fixed : pair));
  1558. free(recomposed);
  1559. uriFreeQueryListA(queryList);
  1560. }
  1561. } // namespace
  1562. TEST(UriSuite, TestQueryListPair) {
  1563. testQueryListPairHelper("one+two+%26+three=%2B", "one two & three", "+");
  1564. testQueryListPairHelper("one=two=three", "one", "two=three", "one=two%3Dthree");
  1565. testQueryListPairHelper("one=two=three=four", "one", "two=three=four", "one=two%3Dthree%3Dfour");
  1566. }
  1567. TEST(UriSuite, TestQueryDissectionBug3590761) {
  1568. int res;
  1569. UriQueryListA * queryList;
  1570. int itemCount;
  1571. const char * const pair = "q=hello&x=&y=";
  1572. res = uriDissectQueryMallocA(&queryList, &itemCount, pair, pair + strlen(pair));
  1573. ASSERT_TRUE(res == URI_SUCCESS);
  1574. ASSERT_TRUE(queryList != NULL);
  1575. ASSERT_TRUE(itemCount == 3);
  1576. ASSERT_TRUE(!strcmp(queryList->key, "q"));
  1577. ASSERT_TRUE(!strcmp(queryList->value, "hello"));
  1578. ASSERT_TRUE(!strcmp(queryList->next->key, "x"));
  1579. ASSERT_TRUE(!strcmp(queryList->next->value, ""));
  1580. ASSERT_TRUE(!strcmp(queryList->next->next->key, "y"));
  1581. ASSERT_TRUE(!strcmp(queryList->next->next->value, ""));
  1582. ASSERT_TRUE(! queryList->next->next->next);
  1583. uriFreeQueryListA(queryList);
  1584. }
  1585. TEST(UriSuite, TestQueryCompositionMathCalc) {
  1586. UriQueryListA second = { /*.key =*/ "k2", /*.value =*/ "v2", /*.next =*/ NULL };
  1587. UriQueryListA first = { /*.key =*/ "k1", /*.value =*/ "v1", /*.next =*/ &second };
  1588. int charsRequired;
  1589. ASSERT_TRUE(uriComposeQueryCharsRequiredA(&first, &charsRequired)
  1590. == URI_SUCCESS);
  1591. const int FACTOR = 6; /* due to escaping with normalizeBreaks */
  1592. ASSERT_TRUE((unsigned)charsRequired ==
  1593. FACTOR * strlen(first.key) + 1 + FACTOR * strlen(first.value)
  1594. + 1
  1595. + FACTOR * strlen(second.key) + 1 + FACTOR * strlen(second.value)
  1596. );
  1597. }
  1598. TEST(UriSuite, TestQueryCompositionMathWriteGoogleAutofuzz113244572) {
  1599. UriQueryListA second = { /*.key =*/ "\x11", /*.value =*/ NULL, /*.next =*/ NULL };
  1600. UriQueryListA first = { /*.key =*/ "\x01", /*.value =*/ "\x02", /*.next =*/ &second };
  1601. const UriBool spaceToPlus = URI_TRUE;
  1602. const UriBool normalizeBreaks = URI_FALSE; /* for factor 3 but 6 */
  1603. const int charsRequired = (3 + 1 + 3) + 1 + (3);
  1604. {
  1605. // Minimum space to hold everything fine
  1606. const char * const expected = "%01=%02" "&" "%11";
  1607. char dest[charsRequired + 1];
  1608. int charsWritten;
  1609. ASSERT_TRUE(uriComposeQueryExA(dest, &first, sizeof(dest),
  1610. &charsWritten, spaceToPlus, normalizeBreaks)
  1611. == URI_SUCCESS);
  1612. ASSERT_TRUE(! strcmp(dest, expected));
  1613. ASSERT_TRUE(charsWritten == strlen(expected) + 1);
  1614. }
  1615. {
  1616. // Previous math failed to take ampersand into account
  1617. char dest[charsRequired + 1 - 1];
  1618. int charsWritten;
  1619. ASSERT_TRUE(uriComposeQueryExA(dest, &first, sizeof(dest),
  1620. &charsWritten, spaceToPlus, normalizeBreaks)
  1621. == URI_ERROR_OUTPUT_TOO_LARGE);
  1622. }
  1623. }
  1624. TEST(UriSuite, TestFreeCrashBug20080827) {
  1625. char const * const sourceUri = "abc";
  1626. char const * const baseUri = "http://www.example.org/";
  1627. int res;
  1628. UriParserStateA state;
  1629. UriUriA absoluteDest;
  1630. UriUriA relativeSource;
  1631. UriUriA absoluteBase;
  1632. state.uri = &relativeSource;
  1633. res = uriParseUriA(&state, sourceUri);
  1634. ASSERT_TRUE(res == URI_SUCCESS);
  1635. state.uri = &absoluteBase;
  1636. res = uriParseUriA(&state, baseUri);
  1637. ASSERT_TRUE(res == URI_SUCCESS);
  1638. res = uriRemoveBaseUriA(&absoluteDest, &relativeSource, &absoluteBase, URI_FALSE);
  1639. ASSERT_TRUE(res == URI_ERROR_REMOVEBASE_REL_SOURCE);
  1640. uriFreeUriMembersA(&relativeSource);
  1641. uriFreeUriMembersA(&absoluteBase);
  1642. uriFreeUriMembersA(&absoluteDest); // Crashed here
  1643. }
  1644. TEST(UriSuite, TestInvalidInputBug16) {
  1645. UriParserStateA stateA;
  1646. UriUriA uriA;
  1647. stateA.uri = &uriA;
  1648. const char * const input = "A>B";
  1649. const int res = uriParseUriA(&stateA, input);
  1650. ASSERT_TRUE(res == URI_ERROR_SYNTAX);
  1651. ASSERT_TRUE(stateA.errorPos == input + 1);
  1652. ASSERT_TRUE(stateA.errorCode == URI_ERROR_SYNTAX); /* failed previously */
  1653. uriFreeUriMembersA(&uriA);
  1654. }
  1655. namespace {
  1656. void testEqualsHelper(const char * uri_to_test) {
  1657. UriParserStateA state;
  1658. UriUriA uriOne;
  1659. UriUriA uriTwo;
  1660. state.uri = &uriOne;
  1661. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, uri_to_test));
  1662. state.uri = &uriTwo;
  1663. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, uri_to_test));
  1664. ASSERT_TRUE(URI_TRUE == uriEqualsUriA(&uriOne, &uriTwo));
  1665. uriFreeUriMembersA(&uriOne);
  1666. uriFreeUriMembersA(&uriTwo);
  1667. }
  1668. } // namespace
  1669. TEST(UriSuite, TestEquals) {
  1670. testEqualsHelper("http://host");
  1671. testEqualsHelper("http://host:123");
  1672. testEqualsHelper("http://foo:bar@host:123");
  1673. testEqualsHelper("http://foo:bar@host:123/");
  1674. testEqualsHelper("http://foo:bar@host:123/path");
  1675. testEqualsHelper("http://foo:bar@host:123/path?query");
  1676. testEqualsHelper("http://foo:bar@host:123/path?query#fragment");
  1677. testEqualsHelper("path");
  1678. testEqualsHelper("/path");
  1679. testEqualsHelper("/path/");
  1680. testEqualsHelper("//path/");
  1681. testEqualsHelper("//host");
  1682. testEqualsHelper("//host:123");
  1683. }
  1684. TEST(UriSuite, TestHostTextTerminationIssue15) {
  1685. UriParserStateA state;
  1686. UriUriA uri;
  1687. state.uri = &uri;
  1688. // Empty host and port
  1689. const char * const emptyHostWithPortUri = "//:123";
  1690. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, emptyHostWithPortUri));
  1691. ASSERT_TRUE(uri.hostText.first == emptyHostWithPortUri + strlen("//"));
  1692. ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0);
  1693. ASSERT_TRUE(uri.portText.first == emptyHostWithPortUri
  1694. + strlen("//:"));
  1695. ASSERT_TRUE(uri.portText.afterLast == uri.portText.first
  1696. + strlen("123"));
  1697. uriFreeUriMembersA(&uri);
  1698. // Non-empty host and port
  1699. const char * const hostWithPortUri = "//h:123";
  1700. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, hostWithPortUri));
  1701. ASSERT_TRUE(uri.hostText.first == hostWithPortUri + strlen("//"));
  1702. ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first
  1703. + strlen("h"));
  1704. ASSERT_TRUE(uri.portText.first == hostWithPortUri + strlen("//h:"));
  1705. ASSERT_TRUE(uri.portText.afterLast == uri.portText.first
  1706. + strlen("123"));
  1707. uriFreeUriMembersA(&uri);
  1708. // Empty host, empty user info
  1709. const char * const emptyHostEmptyUserInfoUri = "//@";
  1710. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state,
  1711. emptyHostEmptyUserInfoUri));
  1712. ASSERT_TRUE(uri.userInfo.first == emptyHostEmptyUserInfoUri
  1713. + strlen("//"));
  1714. ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first + 0);
  1715. ASSERT_TRUE(uri.hostText.first == emptyHostEmptyUserInfoUri
  1716. + strlen("//@"));
  1717. ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0);
  1718. uriFreeUriMembersA(&uri);
  1719. // Non-empty host, empty user info
  1720. const char * const hostEmptyUserInfoUri = "//@h";
  1721. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, hostEmptyUserInfoUri));
  1722. ASSERT_TRUE(uri.userInfo.first == hostEmptyUserInfoUri + strlen("//"));
  1723. ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first + 0);
  1724. ASSERT_TRUE(uri.hostText.first == hostEmptyUserInfoUri
  1725. + strlen("//@"));
  1726. ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first
  1727. + strlen("h"));
  1728. uriFreeUriMembersA(&uri);
  1729. // Empty host, non-empty user info
  1730. const char * const emptyHostWithUserInfoUri = "//:@";
  1731. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state,
  1732. emptyHostWithUserInfoUri));
  1733. ASSERT_TRUE(uri.userInfo.first == emptyHostWithUserInfoUri
  1734. + strlen("//"));
  1735. ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first + 1);
  1736. ASSERT_TRUE(uri.hostText.first == emptyHostWithUserInfoUri
  1737. + strlen("//:@"));
  1738. ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0);
  1739. uriFreeUriMembersA(&uri);
  1740. // Exact case from issue #15
  1741. const char * const issue15Uri = "//:%aa@";
  1742. ASSERT_TRUE(URI_SUCCESS == uriParseUriA(&state, issue15Uri));
  1743. ASSERT_TRUE(uri.userInfo.first == issue15Uri + strlen("//"));
  1744. ASSERT_TRUE(uri.userInfo.afterLast == uri.userInfo.first
  1745. + strlen(":%aa"));
  1746. ASSERT_TRUE(uri.hostText.first == issue15Uri + strlen("//:%aa@"));
  1747. ASSERT_TRUE(uri.hostText.afterLast == uri.hostText.first + 0);
  1748. uriFreeUriMembersA(&uri);
  1749. }
  1750. namespace {
  1751. void testCompareRangeHelper(const char * a, const char * b, int expected, bool avoidNullRange = true) {
  1752. UriTextRangeA ra;
  1753. UriTextRangeA rb;
  1754. if (a) {
  1755. ra.first = a;
  1756. ra.afterLast = a + strlen(a);
  1757. } else {
  1758. ra.first = NULL;
  1759. ra.afterLast = NULL;
  1760. }
  1761. if (b) {
  1762. rb.first = b;
  1763. rb.afterLast = b + strlen(b);
  1764. } else {
  1765. rb.first = NULL;
  1766. rb.afterLast = NULL;
  1767. }
  1768. const int received = uriCompareRangeA(
  1769. ((a == NULL) && avoidNullRange) ? NULL : &ra,
  1770. ((b == NULL) && avoidNullRange) ? NULL : &rb);
  1771. if (received != expected) {
  1772. printf("Comparing <%s> to <%s> yields %d, expected %d.\n",
  1773. a, b, received, expected);
  1774. }
  1775. ASSERT_TRUE(received == expected);
  1776. }
  1777. } // namespace
  1778. TEST(UriSuite, TestRangeComparison) {
  1779. testCompareRangeHelper("", "", 0);
  1780. testCompareRangeHelper("a", "", 1);
  1781. testCompareRangeHelper("", "a", -1);
  1782. testCompareRangeHelper("a", "a", 0);
  1783. testCompareRangeHelper("a", "b", -1);
  1784. testCompareRangeHelper("b", "a", 1);
  1785. testCompareRangeHelper("a", "aa", -1);
  1786. testCompareRangeHelper("aa", "a", 1);
  1787. // Fixed with 0.8.1:
  1788. testCompareRangeHelper(NULL, "a", -1);
  1789. testCompareRangeHelper("a", NULL, 1);
  1790. testCompareRangeHelper(NULL, NULL, 0);
  1791. // Fixed with 0.8.3
  1792. const bool KEEP_NULL_RANGE = false;
  1793. const bool AVOID_NULL_RANGE = true;
  1794. testCompareRangeHelper(NULL, "", -1, AVOID_NULL_RANGE);
  1795. testCompareRangeHelper(NULL, "", -1, KEEP_NULL_RANGE);
  1796. testCompareRangeHelper("", NULL, 1, AVOID_NULL_RANGE);
  1797. testCompareRangeHelper("", NULL, 1, KEEP_NULL_RANGE);
  1798. }
  1799. namespace {
  1800. void testRemoveBaseUriHelper(const char * expected,
  1801. const char * absSourceStr,
  1802. const char * absBaseStr) {
  1803. UriParserStateA state;
  1804. UriUriA absSource;
  1805. UriUriA absBase;
  1806. UriUriA dest;
  1807. state.uri = &absSource;
  1808. ASSERT_TRUE(uriParseUriA(&state, absSourceStr) == URI_SUCCESS);
  1809. state.uri = &absBase;
  1810. ASSERT_TRUE(uriParseUriA(&state, absBaseStr) == URI_SUCCESS);
  1811. ASSERT_TRUE(uriRemoveBaseUriA(&dest, &absSource, &absBase, URI_FALSE)
  1812. == URI_SUCCESS);
  1813. int size = 0;
  1814. ASSERT_TRUE(uriToStringCharsRequiredA(&dest, &size) == URI_SUCCESS);
  1815. char * const buffer = (char *)malloc(size + 1);
  1816. ASSERT_TRUE(buffer);
  1817. ASSERT_TRUE(uriToStringA(buffer, &dest, size + 1, &size)
  1818. == URI_SUCCESS);
  1819. if (strcmp(buffer, expected)) {
  1820. printf("Expected \"%s\" but got \"%s\"\n", expected, buffer);
  1821. ASSERT_TRUE(0);
  1822. }
  1823. free(buffer);
  1824. uriFreeUriMembersA(&absSource);
  1825. uriFreeUriMembersA(&absBase);
  1826. uriFreeUriMembersA(&dest);
  1827. }
  1828. } // namespace
  1829. TEST(UriSuite, TestRangeComparisonRemoveBaseUriIssue19) {
  1830. // scheme
  1831. testRemoveBaseUriHelper("scheme://host/source",
  1832. "scheme://host/source",
  1833. "schemelonger://host/base");
  1834. testRemoveBaseUriHelper("schemelonger://host/source",
  1835. "schemelonger://host/source",
  1836. "scheme://host/base");
  1837. // hostText
  1838. testRemoveBaseUriHelper("//host/source",
  1839. "http://host/source",
  1840. "http://hostlonger/base");
  1841. testRemoveBaseUriHelper("//hostlonger/source",
  1842. "http://hostlonger/source",
  1843. "http://host/base");
  1844. // hostData.ipFuture
  1845. testRemoveBaseUriHelper("//[v7.host]/source",
  1846. "http://[v7.host]/source",
  1847. "http://[v7.hostlonger]/base");
  1848. testRemoveBaseUriHelper("//[v7.hostlonger]/source",
  1849. "http://[v7.hostlonger]/source",
  1850. "http://host/base");
  1851. // path
  1852. testRemoveBaseUriHelper("path1",
  1853. "http://host/path1",
  1854. "http://host/path111");
  1855. testRemoveBaseUriHelper("../path1/path2",
  1856. "http://host/path1/path2",
  1857. "http://host/path111/path222");
  1858. testRemoveBaseUriHelper("path111",
  1859. "http://host/path111",
  1860. "http://host/path1");
  1861. testRemoveBaseUriHelper("../path111/path222",
  1862. "http://host/path111/path222",
  1863. "http://host/path1/path2");
  1864. // Exact issue #19
  1865. testRemoveBaseUriHelper("//example/x/abc",
  1866. "http://example/x/abc",
  1867. "http://example2/x/y/z");
  1868. }
  1869. TEST(ErrorPosSuite, TestErrorPosIPvFuture) {
  1870. UriUriA uri;
  1871. const char * errorPos;
  1872. const char * const uriText = "http://[vA.123456"; // missing "]"
  1873. EXPECT_EQ(uriParseSingleUriA(&uri, uriText, &errorPos),
  1874. URI_ERROR_SYNTAX);
  1875. EXPECT_EQ(errorPos, uriText + strlen(uriText));
  1876. }
  1877. TEST(UriParseSingleSuite, Success) {
  1878. UriUriA uri;
  1879. EXPECT_EQ(uriParseSingleUriA(&uri, "file:///home/user/song.mp3", NULL),
  1880. URI_SUCCESS);
  1881. uriFreeUriMembersA(&uri);
  1882. }
  1883. TEST(UriParseSingleSuite, ErrorSyntaxParseErrorSetsErrorPos) {
  1884. UriUriA uri;
  1885. const char * errorPos;
  1886. const char * const uriString = "abc{}def";
  1887. EXPECT_EQ(uriParseSingleUriA(&uri, uriString, &errorPos),
  1888. URI_ERROR_SYNTAX);
  1889. EXPECT_EQ(errorPos, uriString + strlen("abc"));
  1890. uriFreeUriMembersA(&uri);
  1891. }
  1892. TEST(UriParseSingleSuite, ErrorNullFirstDetected) {
  1893. UriUriA uri;
  1894. const char * errorPos;
  1895. EXPECT_EQ(uriParseSingleUriExA(&uri, NULL, "notnull", &errorPos),
  1896. URI_ERROR_NULL);
  1897. }
  1898. TEST(UriParseSingleSuite, ErrorNullAfterLastDetected) {
  1899. UriUriA uri;
  1900. EXPECT_EQ(uriParseSingleUriExA(&uri, "foo", NULL, NULL), URI_SUCCESS);
  1901. uriFreeUriMembersA(&uri);
  1902. }
  1903. TEST(UriParseSingleSuite, ErrorNullMemoryManagerDetected) {
  1904. UriUriA uri;
  1905. const char * errorPos;
  1906. const char * const uriString = "somethingwellformed";
  1907. EXPECT_EQ(uriParseSingleUriExMmA(&uri,
  1908. uriString,
  1909. uriString + strlen(uriString),
  1910. &errorPos, NULL), URI_SUCCESS);
  1911. EXPECT_EQ(uriFreeUriMembersMmA(&uri, NULL), URI_SUCCESS);
  1912. }
  1913. TEST(FreeUriMembersSuite, MultiFreeWorksFine) {
  1914. UriUriA uri;
  1915. EXPECT_EQ(uriParseSingleUriA(&uri, "file:///home/user/song.mp3", NULL),
  1916. URI_SUCCESS);
  1917. UriUriA uriBackup = uri;
  1918. EXPECT_EQ(memcmp(&uriBackup, &uri, sizeof(UriUriA)), 0);
  1919. uriFreeUriMembersA(&uri);
  1920. // Did some pointers change (to NULL)?
  1921. EXPECT_NE(memcmp(&uriBackup, &uri, sizeof(UriUriA)), 0);
  1922. uriFreeUriMembersA(&uri); // second time
  1923. }
  1924. namespace {
  1925. void testFreeUriMembersFreesHostText(const char *const uriFirst) { // issue #121
  1926. const char *const uriAfterLast = uriFirst + strlen(uriFirst);
  1927. UriUriA uri;
  1928. EXPECT_EQ(uriParseSingleUriA(&uri, uriFirst, NULL), URI_SUCCESS);
  1929. EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS);
  1930. EXPECT_EQ(uri.owner, URI_TRUE);
  1931. EXPECT_TRUE(uri.hostText.first);
  1932. EXPECT_TRUE(uri.hostText.afterLast);
  1933. EXPECT_NE(uri.hostText.first, uri.hostText.afterLast);
  1934. URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast);
  1935. uriFreeUriMembersA(&uri);
  1936. EXPECT_FALSE(uri.hostText.first);
  1937. EXPECT_FALSE(uri.hostText.afterLast);
  1938. uriFreeUriMembersA(&uri); // second time
  1939. }
  1940. } // namespace
  1941. TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextIp4) { // issue #121
  1942. testFreeUriMembersFreesHostText("//192.0.2.0"); // RFC 5737
  1943. }
  1944. TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextIp6) { // issue #121
  1945. testFreeUriMembersFreesHostText("//[2001:db8::]"); // RFC 3849
  1946. }
  1947. TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextRegname) { // issue #121
  1948. testFreeUriMembersFreesHostText("//host123.test"); // RFC 6761
  1949. }
  1950. TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextFuture) { // issue #121
  1951. testFreeUriMembersFreesHostText("//[v7.X]"); // arbitrary IPvFuture
  1952. }
  1953. TEST(MakeOwnerSuite, MakeOwner) {
  1954. const char * const uriString = "scheme://user:pass@[v7.X]:55555/path/../path/?query#fragment";
  1955. UriUriA uri;
  1956. char * uriFirst = strdup(uriString);
  1957. const size_t uriLen = strlen(uriFirst);
  1958. char * uriAfterLast = uriFirst + uriLen;
  1959. EXPECT_EQ(uriParseSingleUriExA(&uri, uriFirst, uriAfterLast, NULL), URI_SUCCESS);
  1960. // After plain parse, all strings should point inside the original URI string
  1961. EXPECT_EQ(uri.owner, URI_FALSE);
  1962. URI_EXPECT_RANGE_BETWEEN(uri.scheme, uriFirst, uriAfterLast);
  1963. URI_EXPECT_RANGE_BETWEEN(uri.userInfo, uriFirst, uriAfterLast);
  1964. URI_EXPECT_RANGE_BETWEEN(uri.hostText, uriFirst, uriAfterLast);
  1965. URI_EXPECT_RANGE_BETWEEN(uri.hostData.ipFuture, uriFirst, uriAfterLast);
  1966. URI_EXPECT_RANGE_BETWEEN(uri.portText, uriFirst, uriAfterLast);
  1967. URI_EXPECT_RANGE_BETWEEN(uri.pathHead->text, uriFirst, uriAfterLast);
  1968. URI_EXPECT_RANGE_BETWEEN(uri.pathHead->next->text, uriFirst, uriAfterLast);
  1969. URI_EXPECT_RANGE_BETWEEN(uri.pathHead->next->next->text, uriFirst, uriAfterLast);
  1970. URI_EXPECT_RANGE_EMPTY(uri.pathHead->next->next->next->text);
  1971. EXPECT_TRUE(uri.pathHead->next->next->next->next == NULL);
  1972. URI_EXPECT_RANGE_BETWEEN(uri.query, uriFirst, uriAfterLast);
  1973. URI_EXPECT_RANGE_BETWEEN(uri.fragment, uriFirst, uriAfterLast);
  1974. EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS);
  1975. // After making owner, *none* of the strings should point inside the original URI string
  1976. EXPECT_EQ(uri.owner, URI_TRUE);
  1977. URI_EXPECT_RANGE_OUTSIDE(uri.scheme, uriFirst, uriAfterLast);
  1978. URI_EXPECT_RANGE_OUTSIDE(uri.userInfo, uriFirst, uriAfterLast);
  1979. URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast);
  1980. URI_EXPECT_RANGE_OUTSIDE(uri.hostData.ipFuture, uriFirst, uriAfterLast);
  1981. URI_EXPECT_RANGE_OUTSIDE(uri.portText, uriFirst, uriAfterLast);
  1982. URI_EXPECT_RANGE_OUTSIDE(uri.pathHead->text, uriFirst, uriAfterLast);
  1983. URI_EXPECT_RANGE_OUTSIDE(uri.pathHead->next->text, uriFirst, uriAfterLast);
  1984. URI_EXPECT_RANGE_OUTSIDE(uri.pathHead->next->next->text, uriFirst, uriAfterLast);
  1985. URI_EXPECT_RANGE_EMPTY(uri.pathHead->next->next->next->text);
  1986. EXPECT_TRUE(uri.pathHead->next->next->next->next == NULL);
  1987. URI_EXPECT_RANGE_OUTSIDE(uri.query, uriFirst, uriAfterLast);
  1988. URI_EXPECT_RANGE_OUTSIDE(uri.fragment, uriFirst, uriAfterLast);
  1989. // Free originally used memory so we'd get violations on access with ASan
  1990. uriAfterLast = NULL;
  1991. free(uriFirst);
  1992. uriFirst = NULL;
  1993. // Can we recompose the URI without accessing any old freed memory?
  1994. int charsRequired;
  1995. EXPECT_EQ(uriToStringCharsRequiredA(&uri, &charsRequired), URI_SUCCESS);
  1996. EXPECT_TRUE((charsRequired >= 0) && (charsRequired >= static_cast<int>(uriLen)));
  1997. char * const uriRemake = new char[charsRequired + 1];
  1998. EXPECT_TRUE(uriRemake != NULL);
  1999. EXPECT_EQ(uriToStringA(uriRemake, &uri, charsRequired + 1, NULL), URI_SUCCESS);
  2000. EXPECT_TRUE(! strcmp(uriString, uriRemake));
  2001. delete [] uriRemake;
  2002. uriFreeUriMembersA(&uri);
  2003. }
  2004. namespace {
  2005. void testMakeOwnerCopiesHostText(const char *const uriFirst) { // issue #121
  2006. const char *const uriAfterLast = uriFirst + strlen(uriFirst);
  2007. UriUriA uri;
  2008. EXPECT_EQ(uriParseSingleUriA(&uri, uriFirst, NULL), URI_SUCCESS);
  2009. EXPECT_EQ(uri.owner, URI_FALSE);
  2010. URI_EXPECT_RANGE_BETWEEN(uri.hostText, uriFirst, uriAfterLast);
  2011. EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS);
  2012. EXPECT_EQ(uri.owner, URI_TRUE);
  2013. URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast);
  2014. uriFreeUriMembersA(&uri);
  2015. uriFreeUriMembersA(&uri); // tried freeing stack pointers before the fix
  2016. }
  2017. } // namespace
  2018. TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextIp4) { // issue #121
  2019. testMakeOwnerCopiesHostText("//192.0.2.0"); // RFC 5737
  2020. }
  2021. TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextIp6) { // issue #121
  2022. testMakeOwnerCopiesHostText("//[2001:db8::]"); // RFC 3849
  2023. }
  2024. TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextRegname) { // issue #121
  2025. testMakeOwnerCopiesHostText("//host123.test"); // RFC 6761
  2026. }
  2027. TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextFuture) { // issue #121
  2028. testMakeOwnerCopiesHostText("//[v7.X]"); // arbitrary IPvFuture
  2029. }
  2030. TEST(ParseIpFourAddressSuite, FourSaneOctets) {
  2031. unsigned char octetOutput[4];
  2032. const char * const ipAddressText = "111.22.3.40";
  2033. const int res = uriParseIpFourAddressA(octetOutput, ipAddressText,
  2034. ipAddressText + strlen(ipAddressText));
  2035. EXPECT_EQ(res, URI_SUCCESS);
  2036. EXPECT_EQ(octetOutput[0], 111);
  2037. EXPECT_EQ(octetOutput[1], 22);
  2038. EXPECT_EQ(octetOutput[2], 3);
  2039. EXPECT_EQ(octetOutput[3], 40);
  2040. }