setters_tests.json 57 KB

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