setters_tests.json 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821
  1. {
  2. "comment": [
  3. "## Tests for setters of https://url.spec.whatwg.org/#urlutils-members",
  4. "",
  5. "This file contains a JSON object.",
  6. "Other than 'comment', each key is an attribute of the `URL` interface",
  7. "defined in WHATWG’s URL Standard.",
  8. "The values are arrays of test case objects for that attribute.",
  9. "",
  10. "To run a test case for the attribute `attr`:",
  11. "",
  12. "* Create a new `URL` object with the value for the 'href' key",
  13. " the constructor single parameter. (Without a base URL.)",
  14. " This must not throw.",
  15. "* Set the attribute `attr` to (invoke its setter with)",
  16. " with the value of for 'new_value' key.",
  17. "* The value for the 'expected' key is another object.",
  18. " For each `key` / `value` pair of that object,",
  19. " get the attribute `key` (invoke its getter).",
  20. " The returned string must be equal to `value`.",
  21. "",
  22. "Note: the 'href' setter is already covered by urltestdata.json."
  23. ],
  24. "protocol": [
  25. {
  26. "comment": "The empty string is not a valid scheme. Setter leaves the URL unchanged.",
  27. "href": "a://example.net",
  28. "new_value": "",
  29. "expected": {
  30. "href": "a://example.net",
  31. "protocol": "a:"
  32. }
  33. },
  34. {
  35. "href": "a://example.net",
  36. "new_value": "b",
  37. "expected": {
  38. "href": "b://example.net",
  39. "protocol": "b:"
  40. }
  41. },
  42. {
  43. "href": "javascript:alert(1)",
  44. "new_value": "defuse",
  45. "expected": {
  46. "href": "defuse:alert(1)",
  47. "protocol": "defuse:"
  48. }
  49. },
  50. {
  51. "comment": "Upper-case ASCII is lower-cased",
  52. "href": "a://example.net",
  53. "new_value": "B",
  54. "expected": {
  55. "href": "b://example.net",
  56. "protocol": "b:"
  57. }
  58. },
  59. {
  60. "comment": "Non-ASCII is rejected",
  61. "href": "a://example.net",
  62. "new_value": "é",
  63. "expected": {
  64. "href": "a://example.net",
  65. "protocol": "a:"
  66. }
  67. },
  68. {
  69. "comment": "No leading digit",
  70. "href": "a://example.net",
  71. "new_value": "0b",
  72. "expected": {
  73. "href": "a://example.net",
  74. "protocol": "a:"
  75. }
  76. },
  77. {
  78. "comment": "No leading punctuation",
  79. "href": "a://example.net",
  80. "new_value": "+b",
  81. "expected": {
  82. "href": "a://example.net",
  83. "protocol": "a:"
  84. }
  85. },
  86. {
  87. "href": "a://example.net",
  88. "new_value": "bC0+-.",
  89. "expected": {
  90. "href": "bc0+-.://example.net",
  91. "protocol": "bc0+-.:"
  92. }
  93. },
  94. {
  95. "comment": "Only some punctuation is acceptable",
  96. "href": "a://example.net",
  97. "new_value": "b,c",
  98. "expected": {
  99. "href": "a://example.net",
  100. "protocol": "a:"
  101. }
  102. },
  103. {
  104. "comment": "Non-ASCII is rejected",
  105. "href": "a://example.net",
  106. "new_value": "bé",
  107. "expected": {
  108. "href": "a://example.net",
  109. "protocol": "a:"
  110. }
  111. },
  112. {
  113. "comment": "Can’t switch from URL containing username/password/port to file",
  114. "href": "http://test@example.net",
  115. "new_value": "file",
  116. "expected": {
  117. "href": "http://test@example.net/",
  118. "protocol": "http:"
  119. }
  120. },
  121. {
  122. "href": "wss://x:x@example.net:1234",
  123. "new_value": "file",
  124. "expected": {
  125. "href": "wss://x:x@example.net:1234/",
  126. "protocol": "wss:"
  127. }
  128. },
  129. {
  130. "comment": "Can’t switch from file URL with no host",
  131. "href": "file://localhost/",
  132. "new_value": "http",
  133. "expected": {
  134. "href": "file:///",
  135. "protocol": "file:"
  136. }
  137. },
  138. {
  139. "href": "file:///test",
  140. "new_value": "gopher",
  141. "expected": {
  142. "href": "file:///test",
  143. "protocol": "file:"
  144. }
  145. },
  146. {
  147. "href": "file:",
  148. "new_value": "wss",
  149. "expected": {
  150. "href": "file:///",
  151. "protocol": "file:"
  152. }
  153. },
  154. {
  155. "comment": "Can’t switch from special scheme to non-special",
  156. "href": "http://example.net",
  157. "new_value": "b",
  158. "expected": {
  159. "href": "http://example.net/",
  160. "protocol": "http:"
  161. }
  162. },
  163. {
  164. "href": "file://hi/path",
  165. "new_value": "s",
  166. "expected": {
  167. "href": "file://hi/path",
  168. "protocol": "file:"
  169. }
  170. },
  171. {
  172. "href": "https://example.net",
  173. "new_value": "s",
  174. "expected": {
  175. "href": "https://example.net/",
  176. "protocol": "https:"
  177. }
  178. },
  179. {
  180. "href": "ftp://example.net",
  181. "new_value": "test",
  182. "expected": {
  183. "href": "ftp://example.net/",
  184. "protocol": "ftp:"
  185. }
  186. },
  187. {
  188. "comment": "Cannot-be-a-base URL doesn’t have a host, but URL in a special scheme must.",
  189. "href": "mailto:me@example.net",
  190. "new_value": "http",
  191. "expected": {
  192. "href": "mailto:me@example.net",
  193. "protocol": "mailto:"
  194. }
  195. },
  196. {
  197. "comment": "Can’t switch from non-special scheme to special",
  198. "href": "ssh://me@example.net",
  199. "new_value": "http",
  200. "expected": {
  201. "href": "ssh://me@example.net",
  202. "protocol": "ssh:"
  203. }
  204. },
  205. {
  206. "href": "ssh://me@example.net",
  207. "new_value": "file",
  208. "expected": {
  209. "href": "ssh://me@example.net",
  210. "protocol": "ssh:"
  211. }
  212. },
  213. {
  214. "href": "ssh://example.net",
  215. "new_value": "file",
  216. "expected": {
  217. "href": "ssh://example.net",
  218. "protocol": "ssh:"
  219. }
  220. },
  221. {
  222. "href": "nonsense:///test",
  223. "new_value": "https",
  224. "expected": {
  225. "href": "nonsense:///test",
  226. "protocol": "nonsense:"
  227. }
  228. },
  229. {
  230. "comment": "Stuff after the first ':' is ignored",
  231. "href": "http://example.net",
  232. "new_value": "https:foo : bar",
  233. "expected": {
  234. "href": "https://example.net/",
  235. "protocol": "https:"
  236. }
  237. },
  238. {
  239. "comment": "Stuff after the first ':' is ignored",
  240. "href": "data:text/html,<p>Test",
  241. "new_value": "view-source+data:foo : bar",
  242. "expected": {
  243. "href": "view-source+data:text/html,<p>Test",
  244. "protocol": "view-source+data:"
  245. }
  246. },
  247. {
  248. "comment": "Port is set to null if it is the default for new scheme.",
  249. "href": "http://foo.com:443/",
  250. "new_value": "https",
  251. "expected": {
  252. "href": "https://foo.com/",
  253. "protocol": "https:",
  254. "port": ""
  255. }
  256. }
  257. ],
  258. "username": [
  259. {
  260. "comment": "No host means no username",
  261. "href": "file:///home/you/index.html",
  262. "new_value": "me",
  263. "expected": {
  264. "href": "file:///home/you/index.html",
  265. "username": ""
  266. }
  267. },
  268. {
  269. "comment": "No host means no username",
  270. "href": "unix:/run/foo.socket",
  271. "new_value": "me",
  272. "expected": {
  273. "href": "unix:/run/foo.socket",
  274. "username": ""
  275. }
  276. },
  277. {
  278. "comment": "Cannot-be-a-base means no username",
  279. "href": "mailto:you@example.net",
  280. "new_value": "me",
  281. "expected": {
  282. "href": "mailto:you@example.net",
  283. "username": ""
  284. }
  285. },
  286. {
  287. "href": "javascript:alert(1)",
  288. "new_value": "wario",
  289. "expected": {
  290. "href": "javascript:alert(1)",
  291. "username": ""
  292. }
  293. },
  294. {
  295. "href": "http://example.net",
  296. "new_value": "me",
  297. "expected": {
  298. "href": "http://me@example.net/",
  299. "username": "me"
  300. }
  301. },
  302. {
  303. "href": "http://:secret@example.net",
  304. "new_value": "me",
  305. "expected": {
  306. "href": "http://me:secret@example.net/",
  307. "username": "me"
  308. }
  309. },
  310. {
  311. "href": "http://me@example.net",
  312. "new_value": "",
  313. "expected": {
  314. "href": "http://example.net/",
  315. "username": ""
  316. }
  317. },
  318. {
  319. "href": "http://me:secret@example.net",
  320. "new_value": "",
  321. "expected": {
  322. "href": "http://:secret@example.net/",
  323. "username": ""
  324. }
  325. },
  326. {
  327. "comment": "UTF-8 percent encoding with the userinfo encode set.",
  328. "href": "http://example.net",
  329. "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
  330. "expected": {
  331. "href": "http://%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/",
  332. "username": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9"
  333. }
  334. },
  335. {
  336. "comment": "Bytes already percent-encoded are left as-is.",
  337. "href": "http://example.net",
  338. "new_value": "%c3%89té",
  339. "expected": {
  340. "href": "http://%c3%89t%C3%A9@example.net/",
  341. "username": "%c3%89t%C3%A9"
  342. }
  343. },
  344. {
  345. "href": "sc:///",
  346. "new_value": "x",
  347. "expected": {
  348. "href": "sc:///",
  349. "username": ""
  350. }
  351. },
  352. {
  353. "href": "javascript://x/",
  354. "new_value": "wario",
  355. "expected": {
  356. "href": "javascript://wario@x/",
  357. "username": "wario"
  358. }
  359. },
  360. {
  361. "href": "file://test/",
  362. "new_value": "test",
  363. "expected": {
  364. "href": "file://test/",
  365. "username": ""
  366. }
  367. }
  368. ],
  369. "password": [
  370. {
  371. "comment": "No host means no password",
  372. "href": "file:///home/me/index.html",
  373. "new_value": "secret",
  374. "expected": {
  375. "href": "file:///home/me/index.html",
  376. "password": ""
  377. }
  378. },
  379. {
  380. "comment": "No host means no password",
  381. "href": "unix:/run/foo.socket",
  382. "new_value": "secret",
  383. "expected": {
  384. "href": "unix:/run/foo.socket",
  385. "password": ""
  386. }
  387. },
  388. {
  389. "comment": "Cannot-be-a-base means no password",
  390. "href": "mailto:me@example.net",
  391. "new_value": "secret",
  392. "expected": {
  393. "href": "mailto:me@example.net",
  394. "password": ""
  395. }
  396. },
  397. {
  398. "href": "http://example.net",
  399. "new_value": "secret",
  400. "expected": {
  401. "href": "http://:secret@example.net/",
  402. "password": "secret"
  403. }
  404. },
  405. {
  406. "href": "http://me@example.net",
  407. "new_value": "secret",
  408. "expected": {
  409. "href": "http://me:secret@example.net/",
  410. "password": "secret"
  411. }
  412. },
  413. {
  414. "href": "http://:secret@example.net",
  415. "new_value": "",
  416. "expected": {
  417. "href": "http://example.net/",
  418. "password": ""
  419. }
  420. },
  421. {
  422. "href": "http://me:secret@example.net",
  423. "new_value": "",
  424. "expected": {
  425. "href": "http://me@example.net/",
  426. "password": ""
  427. }
  428. },
  429. {
  430. "comment": "UTF-8 percent encoding with the userinfo encode set.",
  431. "href": "http://example.net",
  432. "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
  433. "expected": {
  434. "href": "http://:%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/",
  435. "password": "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9"
  436. }
  437. },
  438. {
  439. "comment": "Bytes already percent-encoded are left as-is.",
  440. "href": "http://example.net",
  441. "new_value": "%c3%89té",
  442. "expected": {
  443. "href": "http://:%c3%89t%C3%A9@example.net/",
  444. "password": "%c3%89t%C3%A9"
  445. }
  446. },
  447. {
  448. "href": "sc:///",
  449. "new_value": "x",
  450. "expected": {
  451. "href": "sc:///",
  452. "password": ""
  453. }
  454. },
  455. {
  456. "href": "javascript://x/",
  457. "new_value": "bowser",
  458. "expected": {
  459. "href": "javascript://:bowser@x/",
  460. "password": "bowser"
  461. }
  462. },
  463. {
  464. "href": "file://test/",
  465. "new_value": "test",
  466. "expected": {
  467. "href": "file://test/",
  468. "password": ""
  469. }
  470. }
  471. ],
  472. "host": [
  473. {
  474. "comment": "Non-special scheme",
  475. "href": "sc://x/",
  476. "new_value": "\u0000",
  477. "expected": {
  478. "href": "sc://x/",
  479. "host": "x",
  480. "hostname": "x"
  481. }
  482. },
  483. {
  484. "href": "sc://x/",
  485. "new_value": "\u0009",
  486. "expected": {
  487. "href": "sc:///",
  488. "host": "",
  489. "hostname": ""
  490. }
  491. },
  492. {
  493. "href": "sc://x/",
  494. "new_value": "\u000A",
  495. "expected": {
  496. "href": "sc:///",
  497. "host": "",
  498. "hostname": ""
  499. }
  500. },
  501. {
  502. "href": "sc://x/",
  503. "new_value": "\u000D",
  504. "expected": {
  505. "href": "sc:///",
  506. "host": "",
  507. "hostname": ""
  508. }
  509. },
  510. {
  511. "href": "sc://x/",
  512. "new_value": " ",
  513. "expected": {
  514. "href": "sc://x/",
  515. "host": "x",
  516. "hostname": "x"
  517. }
  518. },
  519. {
  520. "href": "sc://x/",
  521. "new_value": "#",
  522. "expected": {
  523. "href": "sc:///",
  524. "host": "",
  525. "hostname": ""
  526. }
  527. },
  528. {
  529. "href": "sc://x/",
  530. "new_value": "/",
  531. "expected": {
  532. "href": "sc:///",
  533. "host": "",
  534. "hostname": ""
  535. }
  536. },
  537. {
  538. "href": "sc://x/",
  539. "new_value": "?",
  540. "expected": {
  541. "href": "sc:///",
  542. "host": "",
  543. "hostname": ""
  544. }
  545. },
  546. {
  547. "href": "sc://x/",
  548. "new_value": "@",
  549. "expected": {
  550. "href": "sc://x/",
  551. "host": "x",
  552. "hostname": "x"
  553. }
  554. },
  555. {
  556. "href": "sc://x/",
  557. "new_value": "ß",
  558. "expected": {
  559. "href": "sc://%C3%9F/",
  560. "host": "%C3%9F",
  561. "hostname": "%C3%9F"
  562. }
  563. },
  564. {
  565. "comment": "IDNA Nontransitional_Processing",
  566. "href": "https://x/",
  567. "new_value": "ß",
  568. "expected": {
  569. "href": "https://xn--zca/",
  570. "host": "xn--zca",
  571. "hostname": "xn--zca"
  572. }
  573. },
  574. {
  575. "comment": "Cannot-be-a-base means no host",
  576. "href": "mailto:me@example.net",
  577. "new_value": "example.com",
  578. "expected": {
  579. "href": "mailto:me@example.net",
  580. "host": ""
  581. }
  582. },
  583. {
  584. "comment": "Cannot-be-a-base means no password",
  585. "href": "data:text/plain,Stuff",
  586. "new_value": "example.net",
  587. "expected": {
  588. "href": "data:text/plain,Stuff",
  589. "host": ""
  590. }
  591. },
  592. {
  593. "href": "http://example.net",
  594. "new_value": "example.com:8080",
  595. "expected": {
  596. "href": "http://example.com:8080/",
  597. "host": "example.com:8080",
  598. "hostname": "example.com",
  599. "port": "8080"
  600. }
  601. },
  602. {
  603. "comment": "Port number is unchanged if not specified in the new value",
  604. "href": "http://example.net:8080",
  605. "new_value": "example.com",
  606. "expected": {
  607. "href": "http://example.com:8080/",
  608. "host": "example.com:8080",
  609. "hostname": "example.com",
  610. "port": "8080"
  611. }
  612. },
  613. {
  614. "comment": "Port number is unchanged if not specified",
  615. "href": "http://example.net:8080",
  616. "new_value": "example.com:",
  617. "expected": {
  618. "href": "http://example.com:8080/",
  619. "host": "example.com:8080",
  620. "hostname": "example.com",
  621. "port": "8080"
  622. }
  623. },
  624. {
  625. "comment": "The empty host is not valid for special schemes",
  626. "href": "http://example.net",
  627. "new_value": "",
  628. "expected": {
  629. "href": "http://example.net/",
  630. "host": "example.net"
  631. }
  632. },
  633. {
  634. "comment": "The empty host is OK for non-special schemes",
  635. "href": "view-source+http://example.net/foo",
  636. "new_value": "",
  637. "expected": {
  638. "href": "view-source+http:///foo",
  639. "host": ""
  640. }
  641. },
  642. {
  643. "comment": "Path-only URLs can gain a host",
  644. "href": "a:/foo",
  645. "new_value": "example.net",
  646. "expected": {
  647. "href": "a://example.net/foo",
  648. "host": "example.net"
  649. }
  650. },
  651. {
  652. "comment": "IPv4 address syntax is normalized",
  653. "href": "http://example.net",
  654. "new_value": "0x7F000001:8080",
  655. "expected": {
  656. "href": "http://127.0.0.1:8080/",
  657. "host": "127.0.0.1:8080",
  658. "hostname": "127.0.0.1",
  659. "port": "8080"
  660. }
  661. },
  662. {
  663. "comment": "IPv6 address syntax is normalized",
  664. "href": "http://example.net",
  665. "new_value": "[::0:01]:2",
  666. "expected": {
  667. "href": "http://[::1]:2/",
  668. "host": "[::1]:2",
  669. "hostname": "[::1]",
  670. "port": "2"
  671. }
  672. },
  673. {
  674. "comment": "Default port number is removed",
  675. "href": "http://example.net",
  676. "new_value": "example.com:80",
  677. "expected": {
  678. "href": "http://example.com/",
  679. "host": "example.com",
  680. "hostname": "example.com",
  681. "port": ""
  682. }
  683. },
  684. {
  685. "comment": "Default port number is removed",
  686. "href": "https://example.net",
  687. "new_value": "example.com:443",
  688. "expected": {
  689. "href": "https://example.com/",
  690. "host": "example.com",
  691. "hostname": "example.com",
  692. "port": ""
  693. }
  694. },
  695. {
  696. "comment": "Default port number is only removed for the relevant scheme",
  697. "href": "https://example.net",
  698. "new_value": "example.com:80",
  699. "expected": {
  700. "href": "https://example.com:80/",
  701. "host": "example.com:80",
  702. "hostname": "example.com",
  703. "port": "80"
  704. }
  705. },
  706. {
  707. "comment": "Port number is removed if new port is scheme default and existing URL has a non-default port",
  708. "href": "http://example.net:8080",
  709. "new_value": "example.com:80",
  710. "expected": {
  711. "href": "http://example.com/",
  712. "host": "example.com",
  713. "hostname": "example.com",
  714. "port": ""
  715. }
  716. },
  717. {
  718. "comment": "Stuff after a / delimiter is ignored",
  719. "href": "http://example.net/path",
  720. "new_value": "example.com/stuff",
  721. "expected": {
  722. "href": "http://example.com/path",
  723. "host": "example.com",
  724. "hostname": "example.com",
  725. "port": ""
  726. }
  727. },
  728. {
  729. "comment": "Stuff after a / delimiter is ignored",
  730. "href": "http://example.net/path",
  731. "new_value": "example.com:8080/stuff",
  732. "expected": {
  733. "href": "http://example.com:8080/path",
  734. "host": "example.com:8080",
  735. "hostname": "example.com",
  736. "port": "8080"
  737. }
  738. },
  739. {
  740. "comment": "Stuff after a ? delimiter is ignored",
  741. "href": "http://example.net/path",
  742. "new_value": "example.com?stuff",
  743. "expected": {
  744. "href": "http://example.com/path",
  745. "host": "example.com",
  746. "hostname": "example.com",
  747. "port": ""
  748. }
  749. },
  750. {
  751. "comment": "Stuff after a ? delimiter is ignored",
  752. "href": "http://example.net/path",
  753. "new_value": "example.com:8080?stuff",
  754. "expected": {
  755. "href": "http://example.com:8080/path",
  756. "host": "example.com:8080",
  757. "hostname": "example.com",
  758. "port": "8080"
  759. }
  760. },
  761. {
  762. "comment": "Stuff after a # delimiter is ignored",
  763. "href": "http://example.net/path",
  764. "new_value": "example.com#stuff",
  765. "expected": {
  766. "href": "http://example.com/path",
  767. "host": "example.com",
  768. "hostname": "example.com",
  769. "port": ""
  770. }
  771. },
  772. {
  773. "comment": "Stuff after a # delimiter is ignored",
  774. "href": "http://example.net/path",
  775. "new_value": "example.com:8080#stuff",
  776. "expected": {
  777. "href": "http://example.com:8080/path",
  778. "host": "example.com:8080",
  779. "hostname": "example.com",
  780. "port": "8080"
  781. }
  782. },
  783. {
  784. "comment": "Stuff after a \\ delimiter is ignored for special schemes",
  785. "href": "http://example.net/path",
  786. "new_value": "example.com\\stuff",
  787. "expected": {
  788. "href": "http://example.com/path",
  789. "host": "example.com",
  790. "hostname": "example.com",
  791. "port": ""
  792. }
  793. },
  794. {
  795. "comment": "Stuff after a \\ delimiter is ignored for special schemes",
  796. "href": "http://example.net/path",
  797. "new_value": "example.com:8080\\stuff",
  798. "expected": {
  799. "href": "http://example.com:8080/path",
  800. "host": "example.com:8080",
  801. "hostname": "example.com",
  802. "port": "8080"
  803. }
  804. },
  805. {
  806. "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts",
  807. "href": "view-source+http://example.net/path",
  808. "new_value": "example.com\\stuff",
  809. "expected": {
  810. "href": "view-source+http://example.net/path",
  811. "host": "example.net",
  812. "hostname": "example.net",
  813. "port": ""
  814. }
  815. },
  816. {
  817. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  818. "href": "view-source+http://example.net/path",
  819. "new_value": "example.com:8080stuff2",
  820. "expected": {
  821. "href": "view-source+http://example.com:8080/path",
  822. "host": "example.com:8080",
  823. "hostname": "example.com",
  824. "port": "8080"
  825. }
  826. },
  827. {
  828. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  829. "href": "http://example.net/path",
  830. "new_value": "example.com:8080stuff2",
  831. "expected": {
  832. "href": "http://example.com:8080/path",
  833. "host": "example.com:8080",
  834. "hostname": "example.com",
  835. "port": "8080"
  836. }
  837. },
  838. {
  839. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  840. "href": "http://example.net/path",
  841. "new_value": "example.com:8080+2",
  842. "expected": {
  843. "href": "http://example.com:8080/path",
  844. "host": "example.com:8080",
  845. "hostname": "example.com",
  846. "port": "8080"
  847. }
  848. },
  849. {
  850. "comment": "Port numbers are 16 bit integers",
  851. "href": "http://example.net/path",
  852. "new_value": "example.com:65535",
  853. "expected": {
  854. "href": "http://example.com:65535/path",
  855. "host": "example.com:65535",
  856. "hostname": "example.com",
  857. "port": "65535"
  858. }
  859. },
  860. {
  861. "comment": "Port numbers are 16 bit integers, overflowing is an error. Hostname is still set, though.",
  862. "href": "http://example.net/path",
  863. "new_value": "example.com:65536",
  864. "expected": {
  865. "href": "http://example.com/path",
  866. "host": "example.com",
  867. "hostname": "example.com",
  868. "port": ""
  869. }
  870. },
  871. {
  872. "comment": "Broken IPv6",
  873. "href": "http://example.net/",
  874. "new_value": "[google.com]",
  875. "expected": {
  876. "href": "http://example.net/",
  877. "host": "example.net",
  878. "hostname": "example.net"
  879. }
  880. },
  881. {
  882. "href": "http://example.net/",
  883. "new_value": "[::1.2.3.4x]",
  884. "expected": {
  885. "href": "http://example.net/",
  886. "host": "example.net",
  887. "hostname": "example.net"
  888. }
  889. },
  890. {
  891. "href": "http://example.net/",
  892. "new_value": "[::1.2.3.]",
  893. "expected": {
  894. "href": "http://example.net/",
  895. "host": "example.net",
  896. "hostname": "example.net"
  897. }
  898. },
  899. {
  900. "href": "http://example.net/",
  901. "new_value": "[::1.2.]",
  902. "expected": {
  903. "href": "http://example.net/",
  904. "host": "example.net",
  905. "hostname": "example.net"
  906. }
  907. },
  908. {
  909. "href": "http://example.net/",
  910. "new_value": "[::1.]",
  911. "expected": {
  912. "href": "http://example.net/",
  913. "host": "example.net",
  914. "hostname": "example.net"
  915. }
  916. },
  917. {
  918. "href": "file://y/",
  919. "new_value": "x:123",
  920. "expected": {
  921. "href": "file://y/",
  922. "host": "y",
  923. "hostname": "y",
  924. "port": ""
  925. }
  926. },
  927. {
  928. "href": "file://y/",
  929. "new_value": "loc%41lhost",
  930. "expected": {
  931. "href": "file:///",
  932. "host": "",
  933. "hostname": "",
  934. "port": ""
  935. }
  936. },
  937. {
  938. "href": "sc://test@test/",
  939. "new_value": "",
  940. "expected": {
  941. "href": "sc://test@test/",
  942. "host": "test",
  943. "hostname": "test",
  944. "username": "test"
  945. }
  946. },
  947. {
  948. "href": "sc://test:12/",
  949. "new_value": "",
  950. "expected": {
  951. "href": "sc://test:12/",
  952. "host": "test:12",
  953. "hostname": "test",
  954. "port": "12"
  955. }
  956. }
  957. ],
  958. "hostname": [
  959. {
  960. "comment": "Non-special scheme",
  961. "href": "sc://x/",
  962. "new_value": "\u0000",
  963. "expected": {
  964. "href": "sc://x/",
  965. "host": "x",
  966. "hostname": "x"
  967. }
  968. },
  969. {
  970. "href": "sc://x/",
  971. "new_value": "\u0009",
  972. "expected": {
  973. "href": "sc:///",
  974. "host": "",
  975. "hostname": ""
  976. }
  977. },
  978. {
  979. "href": "sc://x/",
  980. "new_value": "\u000A",
  981. "expected": {
  982. "href": "sc:///",
  983. "host": "",
  984. "hostname": ""
  985. }
  986. },
  987. {
  988. "href": "sc://x/",
  989. "new_value": "\u000D",
  990. "expected": {
  991. "href": "sc:///",
  992. "host": "",
  993. "hostname": ""
  994. }
  995. },
  996. {
  997. "href": "sc://x/",
  998. "new_value": " ",
  999. "expected": {
  1000. "href": "sc://x/",
  1001. "host": "x",
  1002. "hostname": "x"
  1003. }
  1004. },
  1005. {
  1006. "href": "sc://x/",
  1007. "new_value": "#",
  1008. "expected": {
  1009. "href": "sc:///",
  1010. "host": "",
  1011. "hostname": ""
  1012. }
  1013. },
  1014. {
  1015. "href": "sc://x/",
  1016. "new_value": "/",
  1017. "expected": {
  1018. "href": "sc:///",
  1019. "host": "",
  1020. "hostname": ""
  1021. }
  1022. },
  1023. {
  1024. "href": "sc://x/",
  1025. "new_value": "?",
  1026. "expected": {
  1027. "href": "sc:///",
  1028. "host": "",
  1029. "hostname": ""
  1030. }
  1031. },
  1032. {
  1033. "href": "sc://x/",
  1034. "new_value": "@",
  1035. "expected": {
  1036. "href": "sc://x/",
  1037. "host": "x",
  1038. "hostname": "x"
  1039. }
  1040. },
  1041. {
  1042. "comment": "Cannot-be-a-base means no host",
  1043. "href": "mailto:me@example.net",
  1044. "new_value": "example.com",
  1045. "expected": {
  1046. "href": "mailto:me@example.net",
  1047. "host": ""
  1048. }
  1049. },
  1050. {
  1051. "comment": "Cannot-be-a-base means no password",
  1052. "href": "data:text/plain,Stuff",
  1053. "new_value": "example.net",
  1054. "expected": {
  1055. "href": "data:text/plain,Stuff",
  1056. "host": ""
  1057. }
  1058. },
  1059. {
  1060. "href": "http://example.net:8080",
  1061. "new_value": "example.com",
  1062. "expected": {
  1063. "href": "http://example.com:8080/",
  1064. "host": "example.com:8080",
  1065. "hostname": "example.com",
  1066. "port": "8080"
  1067. }
  1068. },
  1069. {
  1070. "comment": "The empty host is not valid for special schemes",
  1071. "href": "http://example.net",
  1072. "new_value": "",
  1073. "expected": {
  1074. "href": "http://example.net/",
  1075. "host": "example.net"
  1076. }
  1077. },
  1078. {
  1079. "comment": "The empty host is OK for non-special schemes",
  1080. "href": "view-source+http://example.net/foo",
  1081. "new_value": "",
  1082. "expected": {
  1083. "href": "view-source+http:///foo",
  1084. "host": ""
  1085. }
  1086. },
  1087. {
  1088. "comment": "Path-only URLs can gain a host",
  1089. "href": "a:/foo",
  1090. "new_value": "example.net",
  1091. "expected": {
  1092. "href": "a://example.net/foo",
  1093. "host": "example.net"
  1094. }
  1095. },
  1096. {
  1097. "comment": "IPv4 address syntax is normalized",
  1098. "href": "http://example.net:8080",
  1099. "new_value": "0x7F000001",
  1100. "expected": {
  1101. "href": "http://127.0.0.1:8080/",
  1102. "host": "127.0.0.1:8080",
  1103. "hostname": "127.0.0.1",
  1104. "port": "8080"
  1105. }
  1106. },
  1107. {
  1108. "comment": "IPv6 address syntax is normalized",
  1109. "href": "http://example.net",
  1110. "new_value": "[::0:01]",
  1111. "expected": {
  1112. "href": "http://[::1]/",
  1113. "host": "[::1]",
  1114. "hostname": "[::1]",
  1115. "port": ""
  1116. }
  1117. },
  1118. {
  1119. "comment": "Stuff after a : delimiter is ignored",
  1120. "href": "http://example.net/path",
  1121. "new_value": "example.com:8080",
  1122. "expected": {
  1123. "href": "http://example.com/path",
  1124. "host": "example.com",
  1125. "hostname": "example.com",
  1126. "port": ""
  1127. }
  1128. },
  1129. {
  1130. "comment": "Stuff after a : delimiter is ignored",
  1131. "href": "http://example.net:8080/path",
  1132. "new_value": "example.com:",
  1133. "expected": {
  1134. "href": "http://example.com:8080/path",
  1135. "host": "example.com:8080",
  1136. "hostname": "example.com",
  1137. "port": "8080"
  1138. }
  1139. },
  1140. {
  1141. "comment": "Stuff after a / delimiter is ignored",
  1142. "href": "http://example.net/path",
  1143. "new_value": "example.com/stuff",
  1144. "expected": {
  1145. "href": "http://example.com/path",
  1146. "host": "example.com",
  1147. "hostname": "example.com",
  1148. "port": ""
  1149. }
  1150. },
  1151. {
  1152. "comment": "Stuff after a ? delimiter is ignored",
  1153. "href": "http://example.net/path",
  1154. "new_value": "example.com?stuff",
  1155. "expected": {
  1156. "href": "http://example.com/path",
  1157. "host": "example.com",
  1158. "hostname": "example.com",
  1159. "port": ""
  1160. }
  1161. },
  1162. {
  1163. "comment": "Stuff after a # delimiter is ignored",
  1164. "href": "http://example.net/path",
  1165. "new_value": "example.com#stuff",
  1166. "expected": {
  1167. "href": "http://example.com/path",
  1168. "host": "example.com",
  1169. "hostname": "example.com",
  1170. "port": ""
  1171. }
  1172. },
  1173. {
  1174. "comment": "Stuff after a \\ delimiter is ignored for special schemes",
  1175. "href": "http://example.net/path",
  1176. "new_value": "example.com\\stuff",
  1177. "expected": {
  1178. "href": "http://example.com/path",
  1179. "host": "example.com",
  1180. "hostname": "example.com",
  1181. "port": ""
  1182. }
  1183. },
  1184. {
  1185. "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts",
  1186. "href": "view-source+http://example.net/path",
  1187. "new_value": "example.com\\stuff",
  1188. "expected": {
  1189. "href": "view-source+http://example.net/path",
  1190. "host": "example.net",
  1191. "hostname": "example.net",
  1192. "port": ""
  1193. }
  1194. },
  1195. {
  1196. "comment": "Broken IPv6",
  1197. "href": "http://example.net/",
  1198. "new_value": "[google.com]",
  1199. "expected": {
  1200. "href": "http://example.net/",
  1201. "host": "example.net",
  1202. "hostname": "example.net"
  1203. }
  1204. },
  1205. {
  1206. "href": "http://example.net/",
  1207. "new_value": "[::1.2.3.4x]",
  1208. "expected": {
  1209. "href": "http://example.net/",
  1210. "host": "example.net",
  1211. "hostname": "example.net"
  1212. }
  1213. },
  1214. {
  1215. "href": "http://example.net/",
  1216. "new_value": "[::1.2.3.]",
  1217. "expected": {
  1218. "href": "http://example.net/",
  1219. "host": "example.net",
  1220. "hostname": "example.net"
  1221. }
  1222. },
  1223. {
  1224. "href": "http://example.net/",
  1225. "new_value": "[::1.2.]",
  1226. "expected": {
  1227. "href": "http://example.net/",
  1228. "host": "example.net",
  1229. "hostname": "example.net"
  1230. }
  1231. },
  1232. {
  1233. "href": "http://example.net/",
  1234. "new_value": "[::1.]",
  1235. "expected": {
  1236. "href": "http://example.net/",
  1237. "host": "example.net",
  1238. "hostname": "example.net"
  1239. }
  1240. },
  1241. {
  1242. "href": "file://y/",
  1243. "new_value": "x:123",
  1244. "expected": {
  1245. "href": "file://y/",
  1246. "host": "y",
  1247. "hostname": "y",
  1248. "port": ""
  1249. }
  1250. },
  1251. {
  1252. "href": "file://y/",
  1253. "new_value": "loc%41lhost",
  1254. "expected": {
  1255. "href": "file:///",
  1256. "host": "",
  1257. "hostname": "",
  1258. "port": ""
  1259. }
  1260. },
  1261. {
  1262. "href": "sc://test@test/",
  1263. "new_value": "",
  1264. "expected": {
  1265. "href": "sc://test@test/",
  1266. "host": "test",
  1267. "hostname": "test",
  1268. "username": "test"
  1269. }
  1270. },
  1271. {
  1272. "href": "sc://test:12/",
  1273. "new_value": "",
  1274. "expected": {
  1275. "href": "sc://test:12/",
  1276. "host": "test:12",
  1277. "hostname": "test",
  1278. "port": "12"
  1279. }
  1280. }
  1281. ],
  1282. "port": [
  1283. {
  1284. "href": "http://example.net",
  1285. "new_value": "8080",
  1286. "expected": {
  1287. "href": "http://example.net:8080/",
  1288. "host": "example.net:8080",
  1289. "hostname": "example.net",
  1290. "port": "8080"
  1291. }
  1292. },
  1293. {
  1294. "comment": "Port number is removed if empty is the new value",
  1295. "href": "http://example.net:8080",
  1296. "new_value": "",
  1297. "expected": {
  1298. "href": "http://example.net/",
  1299. "host": "example.net",
  1300. "hostname": "example.net",
  1301. "port": ""
  1302. }
  1303. },
  1304. {
  1305. "comment": "Default port number is removed",
  1306. "href": "http://example.net:8080",
  1307. "new_value": "80",
  1308. "expected": {
  1309. "href": "http://example.net/",
  1310. "host": "example.net",
  1311. "hostname": "example.net",
  1312. "port": ""
  1313. }
  1314. },
  1315. {
  1316. "comment": "Default port number is removed",
  1317. "href": "https://example.net:4433",
  1318. "new_value": "443",
  1319. "expected": {
  1320. "href": "https://example.net/",
  1321. "host": "example.net",
  1322. "hostname": "example.net",
  1323. "port": ""
  1324. }
  1325. },
  1326. {
  1327. "comment": "Default port number is only removed for the relevant scheme",
  1328. "href": "https://example.net",
  1329. "new_value": "80",
  1330. "expected": {
  1331. "href": "https://example.net:80/",
  1332. "host": "example.net:80",
  1333. "hostname": "example.net",
  1334. "port": "80"
  1335. }
  1336. },
  1337. {
  1338. "comment": "Stuff after a / delimiter is ignored",
  1339. "href": "http://example.net/path",
  1340. "new_value": "8080/stuff",
  1341. "expected": {
  1342. "href": "http://example.net:8080/path",
  1343. "host": "example.net:8080",
  1344. "hostname": "example.net",
  1345. "port": "8080"
  1346. }
  1347. },
  1348. {
  1349. "comment": "Stuff after a ? delimiter is ignored",
  1350. "href": "http://example.net/path",
  1351. "new_value": "8080?stuff",
  1352. "expected": {
  1353. "href": "http://example.net:8080/path",
  1354. "host": "example.net:8080",
  1355. "hostname": "example.net",
  1356. "port": "8080"
  1357. }
  1358. },
  1359. {
  1360. "comment": "Stuff after a # delimiter is ignored",
  1361. "href": "http://example.net/path",
  1362. "new_value": "8080#stuff",
  1363. "expected": {
  1364. "href": "http://example.net:8080/path",
  1365. "host": "example.net:8080",
  1366. "hostname": "example.net",
  1367. "port": "8080"
  1368. }
  1369. },
  1370. {
  1371. "comment": "Stuff after a \\ delimiter is ignored for special schemes",
  1372. "href": "http://example.net/path",
  1373. "new_value": "8080\\stuff",
  1374. "expected": {
  1375. "href": "http://example.net:8080/path",
  1376. "host": "example.net:8080",
  1377. "hostname": "example.net",
  1378. "port": "8080"
  1379. }
  1380. },
  1381. {
  1382. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  1383. "href": "view-source+http://example.net/path",
  1384. "new_value": "8080stuff2",
  1385. "expected": {
  1386. "href": "view-source+http://example.net:8080/path",
  1387. "host": "example.net:8080",
  1388. "hostname": "example.net",
  1389. "port": "8080"
  1390. }
  1391. },
  1392. {
  1393. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  1394. "href": "http://example.net/path",
  1395. "new_value": "8080stuff2",
  1396. "expected": {
  1397. "href": "http://example.net:8080/path",
  1398. "host": "example.net:8080",
  1399. "hostname": "example.net",
  1400. "port": "8080"
  1401. }
  1402. },
  1403. {
  1404. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  1405. "href": "http://example.net/path",
  1406. "new_value": "8080+2",
  1407. "expected": {
  1408. "href": "http://example.net:8080/path",
  1409. "host": "example.net:8080",
  1410. "hostname": "example.net",
  1411. "port": "8080"
  1412. }
  1413. },
  1414. {
  1415. "comment": "Port numbers are 16 bit integers",
  1416. "href": "http://example.net/path",
  1417. "new_value": "65535",
  1418. "expected": {
  1419. "href": "http://example.net:65535/path",
  1420. "host": "example.net:65535",
  1421. "hostname": "example.net",
  1422. "port": "65535"
  1423. }
  1424. },
  1425. {
  1426. "comment": "Port numbers are 16 bit integers, overflowing is an error",
  1427. "href": "http://example.net:8080/path",
  1428. "new_value": "65536",
  1429. "expected": {
  1430. "href": "http://example.net:8080/path",
  1431. "host": "example.net:8080",
  1432. "hostname": "example.net",
  1433. "port": "8080"
  1434. }
  1435. },
  1436. {
  1437. "comment": "Port numbers are 16 bit integers, overflowing is an error",
  1438. "href": "non-special://example.net:8080/path",
  1439. "new_value": "65536",
  1440. "expected": {
  1441. "href": "non-special://example.net:8080/path",
  1442. "host": "example.net:8080",
  1443. "hostname": "example.net",
  1444. "port": "8080"
  1445. }
  1446. },
  1447. {
  1448. "href": "file://test/",
  1449. "new_value": "12",
  1450. "expected": {
  1451. "href": "file://test/",
  1452. "port": ""
  1453. }
  1454. },
  1455. {
  1456. "href": "file://localhost/",
  1457. "new_value": "12",
  1458. "expected": {
  1459. "href": "file:///",
  1460. "port": ""
  1461. }
  1462. },
  1463. {
  1464. "href": "non-base:value",
  1465. "new_value": "12",
  1466. "expected": {
  1467. "href": "non-base:value",
  1468. "port": ""
  1469. }
  1470. },
  1471. {
  1472. "href": "sc:///",
  1473. "new_value": "12",
  1474. "expected": {
  1475. "href": "sc:///",
  1476. "port": ""
  1477. }
  1478. },
  1479. {
  1480. "href": "sc://x/",
  1481. "new_value": "12",
  1482. "expected": {
  1483. "href": "sc://x:12/",
  1484. "port": "12"
  1485. }
  1486. },
  1487. {
  1488. "href": "javascript://x/",
  1489. "new_value": "12",
  1490. "expected": {
  1491. "href": "javascript://x:12/",
  1492. "port": "12"
  1493. }
  1494. }
  1495. ],
  1496. "pathname": [
  1497. {
  1498. "comment": "Cannot-be-a-base don’t have a path",
  1499. "href": "mailto:me@example.net",
  1500. "new_value": "/foo",
  1501. "expected": {
  1502. "href": "mailto:me@example.net",
  1503. "pathname": "me@example.net"
  1504. }
  1505. },
  1506. {
  1507. "href": "unix:/run/foo.socket?timeout=10",
  1508. "new_value": "/var/log/../run/bar.socket",
  1509. "expected": {
  1510. "href": "unix:/var/run/bar.socket?timeout=10",
  1511. "pathname": "/var/run/bar.socket"
  1512. }
  1513. },
  1514. {
  1515. "href": "https://example.net#nav",
  1516. "new_value": "home",
  1517. "expected": {
  1518. "href": "https://example.net/home#nav",
  1519. "pathname": "/home"
  1520. }
  1521. },
  1522. {
  1523. "href": "https://example.net#nav",
  1524. "new_value": "../home",
  1525. "expected": {
  1526. "href": "https://example.net/home#nav",
  1527. "pathname": "/home"
  1528. }
  1529. },
  1530. {
  1531. "comment": "\\ is a segment delimiter for 'special' URLs",
  1532. "href": "http://example.net/home?lang=fr#nav",
  1533. "new_value": "\\a\\%2E\\b\\%2e.\\c",
  1534. "expected": {
  1535. "href": "http://example.net/a/c?lang=fr#nav",
  1536. "pathname": "/a/c"
  1537. }
  1538. },
  1539. {
  1540. "comment": "\\ is *not* a segment delimiter for non-'special' URLs",
  1541. "href": "view-source+http://example.net/home?lang=fr#nav",
  1542. "new_value": "\\a\\%2E\\b\\%2e.\\c",
  1543. "expected": {
  1544. "href": "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav",
  1545. "pathname": "/\\a\\%2E\\b\\%2e.\\c"
  1546. }
  1547. },
  1548. {
  1549. "comment": "UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.",
  1550. "href": "a:/",
  1551. "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
  1552. "expected": {
  1553. "href": "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9",
  1554. "pathname": "/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9"
  1555. }
  1556. },
  1557. {
  1558. "comment": "Bytes already percent-encoded are left as-is, including %2E outside dotted segments.",
  1559. "href": "http://example.net",
  1560. "new_value": "%2e%2E%c3%89té",
  1561. "expected": {
  1562. "href": "http://example.net/%2e%2E%c3%89t%C3%A9",
  1563. "pathname": "/%2e%2E%c3%89t%C3%A9"
  1564. }
  1565. },
  1566. {
  1567. "comment": "? needs to be encoded",
  1568. "href": "http://example.net",
  1569. "new_value": "?",
  1570. "expected": {
  1571. "href": "http://example.net/%3F",
  1572. "pathname": "/%3F"
  1573. }
  1574. },
  1575. {
  1576. "comment": "# needs to be encoded",
  1577. "href": "http://example.net",
  1578. "new_value": "#",
  1579. "expected": {
  1580. "href": "http://example.net/%23",
  1581. "pathname": "/%23"
  1582. }
  1583. },
  1584. {
  1585. "comment": "? needs to be encoded, non-special scheme",
  1586. "href": "sc://example.net",
  1587. "new_value": "?",
  1588. "expected": {
  1589. "href": "sc://example.net/%3F",
  1590. "pathname": "/%3F"
  1591. }
  1592. },
  1593. {
  1594. "comment": "# needs to be encoded, non-special scheme",
  1595. "href": "sc://example.net",
  1596. "new_value": "#",
  1597. "expected": {
  1598. "href": "sc://example.net/%23",
  1599. "pathname": "/%23"
  1600. }
  1601. },
  1602. {
  1603. "comment": "File URLs and (back)slashes",
  1604. "href": "file://monkey/",
  1605. "new_value": "\\\\",
  1606. "expected": {
  1607. "href": "file://monkey/",
  1608. "pathname": "/"
  1609. }
  1610. },
  1611. {
  1612. "comment": "File URLs and (back)slashes",
  1613. "href": "file:///unicorn",
  1614. "new_value": "//\\/",
  1615. "expected": {
  1616. "href": "file:///",
  1617. "pathname": "/"
  1618. }
  1619. },
  1620. {
  1621. "comment": "File URLs and (back)slashes",
  1622. "href": "file:///unicorn",
  1623. "new_value": "//monkey/..//",
  1624. "expected": {
  1625. "href": "file:///",
  1626. "pathname": "/"
  1627. }
  1628. }
  1629. ],
  1630. "search": [
  1631. {
  1632. "href": "https://example.net#nav",
  1633. "new_value": "lang=fr",
  1634. "expected": {
  1635. "href": "https://example.net/?lang=fr#nav",
  1636. "search": "?lang=fr"
  1637. }
  1638. },
  1639. {
  1640. "href": "https://example.net?lang=en-US#nav",
  1641. "new_value": "lang=fr",
  1642. "expected": {
  1643. "href": "https://example.net/?lang=fr#nav",
  1644. "search": "?lang=fr"
  1645. }
  1646. },
  1647. {
  1648. "href": "https://example.net?lang=en-US#nav",
  1649. "new_value": "?lang=fr",
  1650. "expected": {
  1651. "href": "https://example.net/?lang=fr#nav",
  1652. "search": "?lang=fr"
  1653. }
  1654. },
  1655. {
  1656. "href": "https://example.net?lang=en-US#nav",
  1657. "new_value": "??lang=fr",
  1658. "expected": {
  1659. "href": "https://example.net/??lang=fr#nav",
  1660. "search": "??lang=fr"
  1661. }
  1662. },
  1663. {
  1664. "href": "https://example.net?lang=en-US#nav",
  1665. "new_value": "?",
  1666. "expected": {
  1667. "href": "https://example.net/?#nav",
  1668. "search": ""
  1669. }
  1670. },
  1671. {
  1672. "href": "https://example.net?lang=en-US#nav",
  1673. "new_value": "",
  1674. "expected": {
  1675. "href": "https://example.net/#nav",
  1676. "search": ""
  1677. }
  1678. },
  1679. {
  1680. "href": "https://example.net?lang=en-US",
  1681. "new_value": "",
  1682. "expected": {
  1683. "href": "https://example.net/",
  1684. "search": ""
  1685. }
  1686. },
  1687. {
  1688. "href": "https://example.net",
  1689. "new_value": "",
  1690. "expected": {
  1691. "href": "https://example.net/",
  1692. "search": ""
  1693. }
  1694. },
  1695. {
  1696. "comment": "UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.",
  1697. "href": "a:/",
  1698. "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
  1699. "expected": {
  1700. "href": "a:/?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9",
  1701. "search": "?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9"
  1702. }
  1703. },
  1704. {
  1705. "comment": "Bytes already percent-encoded are left as-is",
  1706. "href": "http://example.net",
  1707. "new_value": "%c3%89té",
  1708. "expected": {
  1709. "href": "http://example.net/?%c3%89t%C3%A9",
  1710. "search": "?%c3%89t%C3%A9"
  1711. }
  1712. }
  1713. ],
  1714. "hash": [
  1715. {
  1716. "href": "https://example.net",
  1717. "new_value": "main",
  1718. "expected": {
  1719. "href": "https://example.net/#main",
  1720. "hash": "#main"
  1721. }
  1722. },
  1723. {
  1724. "href": "https://example.net#nav",
  1725. "new_value": "main",
  1726. "expected": {
  1727. "href": "https://example.net/#main",
  1728. "hash": "#main"
  1729. }
  1730. },
  1731. {
  1732. "href": "https://example.net?lang=en-US",
  1733. "new_value": "##nav",
  1734. "expected": {
  1735. "href": "https://example.net/?lang=en-US##nav",
  1736. "hash": "##nav"
  1737. }
  1738. },
  1739. {
  1740. "href": "https://example.net?lang=en-US#nav",
  1741. "new_value": "#main",
  1742. "expected": {
  1743. "href": "https://example.net/?lang=en-US#main",
  1744. "hash": "#main"
  1745. }
  1746. },
  1747. {
  1748. "href": "https://example.net?lang=en-US#nav",
  1749. "new_value": "#",
  1750. "expected": {
  1751. "href": "https://example.net/?lang=en-US#",
  1752. "hash": ""
  1753. }
  1754. },
  1755. {
  1756. "href": "https://example.net?lang=en-US#nav",
  1757. "new_value": "",
  1758. "expected": {
  1759. "href": "https://example.net/?lang=en-US",
  1760. "hash": ""
  1761. }
  1762. },
  1763. {
  1764. "href": "http://example.net",
  1765. "new_value": "#foo bar",
  1766. "expected": {
  1767. "href": "http://example.net/#foo%20bar",
  1768. "hash": "#foo%20bar"
  1769. }
  1770. },
  1771. {
  1772. "href": "http://example.net",
  1773. "new_value": "#foo\"bar",
  1774. "expected": {
  1775. "href": "http://example.net/#foo%22bar",
  1776. "hash": "#foo%22bar"
  1777. }
  1778. },
  1779. {
  1780. "href": "http://example.net",
  1781. "new_value": "#foo<bar",
  1782. "expected": {
  1783. "href": "http://example.net/#foo%3Cbar",
  1784. "hash": "#foo%3Cbar"
  1785. }
  1786. },
  1787. {
  1788. "href": "http://example.net",
  1789. "new_value": "#foo>bar",
  1790. "expected": {
  1791. "href": "http://example.net/#foo%3Ebar",
  1792. "hash": "#foo%3Ebar"
  1793. }
  1794. },
  1795. {
  1796. "href": "http://example.net",
  1797. "new_value": "#foo`bar",
  1798. "expected": {
  1799. "href": "http://example.net/#foo%60bar",
  1800. "hash": "#foo%60bar"
  1801. }
  1802. },
  1803. {
  1804. "comment": "Bytes already percent-encoded are left as-is",
  1805. "href": "http://example.net",
  1806. "new_value": "%c3%89té",
  1807. "expected": {
  1808. "href": "http://example.net/#%c3%89t%C3%A9",
  1809. "hash": "#%c3%89t%C3%A9"
  1810. }
  1811. },
  1812. {
  1813. "href": "javascript:alert(1)",
  1814. "new_value": "castle",
  1815. "expected": {
  1816. "href": "javascript:alert(1)#castle",
  1817. "hash": "#castle"
  1818. }
  1819. }
  1820. ]
  1821. }