setters_tests.json 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866
  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": "file://hi/x",
  955. "new_value": "",
  956. "expected": {
  957. "href": "file:///x",
  958. "host": "",
  959. "hostname": "",
  960. "port": ""
  961. }
  962. },
  963. {
  964. "href": "sc://test@test/",
  965. "new_value": "",
  966. "expected": {
  967. "href": "sc://test@test/",
  968. "host": "test",
  969. "hostname": "test",
  970. "username": "test"
  971. }
  972. },
  973. {
  974. "href": "sc://test:12/",
  975. "new_value": "",
  976. "expected": {
  977. "href": "sc://test:12/",
  978. "host": "test:12",
  979. "hostname": "test",
  980. "port": "12"
  981. }
  982. }
  983. ],
  984. "hostname": [
  985. {
  986. "comment": "Non-special scheme",
  987. "href": "sc://x/",
  988. "new_value": "\u0000",
  989. "expected": {
  990. "href": "sc://x/",
  991. "host": "x",
  992. "hostname": "x"
  993. }
  994. },
  995. {
  996. "href": "sc://x/",
  997. "new_value": "\u0009",
  998. "expected": {
  999. "href": "sc:///",
  1000. "host": "",
  1001. "hostname": ""
  1002. }
  1003. },
  1004. {
  1005. "href": "sc://x/",
  1006. "new_value": "\u000A",
  1007. "expected": {
  1008. "href": "sc:///",
  1009. "host": "",
  1010. "hostname": ""
  1011. }
  1012. },
  1013. {
  1014. "href": "sc://x/",
  1015. "new_value": "\u000D",
  1016. "expected": {
  1017. "href": "sc:///",
  1018. "host": "",
  1019. "hostname": ""
  1020. }
  1021. },
  1022. {
  1023. "href": "sc://x/",
  1024. "new_value": " ",
  1025. "expected": {
  1026. "href": "sc://x/",
  1027. "host": "x",
  1028. "hostname": "x"
  1029. }
  1030. },
  1031. {
  1032. "href": "sc://x/",
  1033. "new_value": "#",
  1034. "expected": {
  1035. "href": "sc:///",
  1036. "host": "",
  1037. "hostname": ""
  1038. }
  1039. },
  1040. {
  1041. "href": "sc://x/",
  1042. "new_value": "/",
  1043. "expected": {
  1044. "href": "sc:///",
  1045. "host": "",
  1046. "hostname": ""
  1047. }
  1048. },
  1049. {
  1050. "href": "sc://x/",
  1051. "new_value": "?",
  1052. "expected": {
  1053. "href": "sc:///",
  1054. "host": "",
  1055. "hostname": ""
  1056. }
  1057. },
  1058. {
  1059. "href": "sc://x/",
  1060. "new_value": "@",
  1061. "expected": {
  1062. "href": "sc://x/",
  1063. "host": "x",
  1064. "hostname": "x"
  1065. }
  1066. },
  1067. {
  1068. "comment": "Cannot-be-a-base means no host",
  1069. "href": "mailto:me@example.net",
  1070. "new_value": "example.com",
  1071. "expected": {
  1072. "href": "mailto:me@example.net",
  1073. "host": ""
  1074. }
  1075. },
  1076. {
  1077. "comment": "Cannot-be-a-base means no password",
  1078. "href": "data:text/plain,Stuff",
  1079. "new_value": "example.net",
  1080. "expected": {
  1081. "href": "data:text/plain,Stuff",
  1082. "host": ""
  1083. }
  1084. },
  1085. {
  1086. "href": "http://example.net:8080",
  1087. "new_value": "example.com",
  1088. "expected": {
  1089. "href": "http://example.com:8080/",
  1090. "host": "example.com:8080",
  1091. "hostname": "example.com",
  1092. "port": "8080"
  1093. }
  1094. },
  1095. {
  1096. "comment": "The empty host is not valid for special schemes",
  1097. "href": "http://example.net",
  1098. "new_value": "",
  1099. "expected": {
  1100. "href": "http://example.net/",
  1101. "host": "example.net"
  1102. }
  1103. },
  1104. {
  1105. "comment": "The empty host is OK for non-special schemes",
  1106. "href": "view-source+http://example.net/foo",
  1107. "new_value": "",
  1108. "expected": {
  1109. "href": "view-source+http:///foo",
  1110. "host": ""
  1111. }
  1112. },
  1113. {
  1114. "comment": "Path-only URLs can gain a host",
  1115. "href": "a:/foo",
  1116. "new_value": "example.net",
  1117. "expected": {
  1118. "href": "a://example.net/foo",
  1119. "host": "example.net"
  1120. }
  1121. },
  1122. {
  1123. "comment": "IPv4 address syntax is normalized",
  1124. "href": "http://example.net:8080",
  1125. "new_value": "0x7F000001",
  1126. "expected": {
  1127. "href": "http://127.0.0.1:8080/",
  1128. "host": "127.0.0.1:8080",
  1129. "hostname": "127.0.0.1",
  1130. "port": "8080"
  1131. }
  1132. },
  1133. {
  1134. "comment": "IPv6 address syntax is normalized",
  1135. "href": "http://example.net",
  1136. "new_value": "[::0:01]",
  1137. "expected": {
  1138. "href": "http://[::1]/",
  1139. "host": "[::1]",
  1140. "hostname": "[::1]",
  1141. "port": ""
  1142. }
  1143. },
  1144. {
  1145. "comment": "Stuff after a : delimiter is ignored",
  1146. "href": "http://example.net/path",
  1147. "new_value": "example.com:8080",
  1148. "expected": {
  1149. "href": "http://example.com/path",
  1150. "host": "example.com",
  1151. "hostname": "example.com",
  1152. "port": ""
  1153. }
  1154. },
  1155. {
  1156. "comment": "Stuff after a : delimiter is ignored",
  1157. "href": "http://example.net:8080/path",
  1158. "new_value": "example.com:",
  1159. "expected": {
  1160. "href": "http://example.com:8080/path",
  1161. "host": "example.com:8080",
  1162. "hostname": "example.com",
  1163. "port": "8080"
  1164. }
  1165. },
  1166. {
  1167. "comment": "Stuff after a / delimiter is ignored",
  1168. "href": "http://example.net/path",
  1169. "new_value": "example.com/stuff",
  1170. "expected": {
  1171. "href": "http://example.com/path",
  1172. "host": "example.com",
  1173. "hostname": "example.com",
  1174. "port": ""
  1175. }
  1176. },
  1177. {
  1178. "comment": "Stuff after a ? delimiter is ignored",
  1179. "href": "http://example.net/path",
  1180. "new_value": "example.com?stuff",
  1181. "expected": {
  1182. "href": "http://example.com/path",
  1183. "host": "example.com",
  1184. "hostname": "example.com",
  1185. "port": ""
  1186. }
  1187. },
  1188. {
  1189. "comment": "Stuff after a # delimiter is ignored",
  1190. "href": "http://example.net/path",
  1191. "new_value": "example.com#stuff",
  1192. "expected": {
  1193. "href": "http://example.com/path",
  1194. "host": "example.com",
  1195. "hostname": "example.com",
  1196. "port": ""
  1197. }
  1198. },
  1199. {
  1200. "comment": "Stuff after a \\ delimiter is ignored for special schemes",
  1201. "href": "http://example.net/path",
  1202. "new_value": "example.com\\stuff",
  1203. "expected": {
  1204. "href": "http://example.com/path",
  1205. "host": "example.com",
  1206. "hostname": "example.com",
  1207. "port": ""
  1208. }
  1209. },
  1210. {
  1211. "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts",
  1212. "href": "view-source+http://example.net/path",
  1213. "new_value": "example.com\\stuff",
  1214. "expected": {
  1215. "href": "view-source+http://example.net/path",
  1216. "host": "example.net",
  1217. "hostname": "example.net",
  1218. "port": ""
  1219. }
  1220. },
  1221. {
  1222. "comment": "Broken IPv6",
  1223. "href": "http://example.net/",
  1224. "new_value": "[google.com]",
  1225. "expected": {
  1226. "href": "http://example.net/",
  1227. "host": "example.net",
  1228. "hostname": "example.net"
  1229. }
  1230. },
  1231. {
  1232. "href": "http://example.net/",
  1233. "new_value": "[::1.2.3.4x]",
  1234. "expected": {
  1235. "href": "http://example.net/",
  1236. "host": "example.net",
  1237. "hostname": "example.net"
  1238. }
  1239. },
  1240. {
  1241. "href": "http://example.net/",
  1242. "new_value": "[::1.2.3.]",
  1243. "expected": {
  1244. "href": "http://example.net/",
  1245. "host": "example.net",
  1246. "hostname": "example.net"
  1247. }
  1248. },
  1249. {
  1250. "href": "http://example.net/",
  1251. "new_value": "[::1.2.]",
  1252. "expected": {
  1253. "href": "http://example.net/",
  1254. "host": "example.net",
  1255. "hostname": "example.net"
  1256. }
  1257. },
  1258. {
  1259. "href": "http://example.net/",
  1260. "new_value": "[::1.]",
  1261. "expected": {
  1262. "href": "http://example.net/",
  1263. "host": "example.net",
  1264. "hostname": "example.net"
  1265. }
  1266. },
  1267. {
  1268. "href": "file://y/",
  1269. "new_value": "x:123",
  1270. "expected": {
  1271. "href": "file://y/",
  1272. "host": "y",
  1273. "hostname": "y",
  1274. "port": ""
  1275. }
  1276. },
  1277. {
  1278. "href": "file://y/",
  1279. "new_value": "loc%41lhost",
  1280. "expected": {
  1281. "href": "file:///",
  1282. "host": "",
  1283. "hostname": "",
  1284. "port": ""
  1285. }
  1286. },
  1287. {
  1288. "href": "file://hi/x",
  1289. "new_value": "",
  1290. "expected": {
  1291. "href": "file:///x",
  1292. "host": "",
  1293. "hostname": "",
  1294. "port": ""
  1295. }
  1296. },
  1297. {
  1298. "href": "sc://test@test/",
  1299. "new_value": "",
  1300. "expected": {
  1301. "href": "sc://test@test/",
  1302. "host": "test",
  1303. "hostname": "test",
  1304. "username": "test"
  1305. }
  1306. },
  1307. {
  1308. "href": "sc://test:12/",
  1309. "new_value": "",
  1310. "expected": {
  1311. "href": "sc://test:12/",
  1312. "host": "test:12",
  1313. "hostname": "test",
  1314. "port": "12"
  1315. }
  1316. }
  1317. ],
  1318. "port": [
  1319. {
  1320. "href": "http://example.net",
  1321. "new_value": "8080",
  1322. "expected": {
  1323. "href": "http://example.net:8080/",
  1324. "host": "example.net:8080",
  1325. "hostname": "example.net",
  1326. "port": "8080"
  1327. }
  1328. },
  1329. {
  1330. "comment": "Port number is removed if empty is the new value",
  1331. "href": "http://example.net:8080",
  1332. "new_value": "",
  1333. "expected": {
  1334. "href": "http://example.net/",
  1335. "host": "example.net",
  1336. "hostname": "example.net",
  1337. "port": ""
  1338. }
  1339. },
  1340. {
  1341. "comment": "Default port number is removed",
  1342. "href": "http://example.net:8080",
  1343. "new_value": "80",
  1344. "expected": {
  1345. "href": "http://example.net/",
  1346. "host": "example.net",
  1347. "hostname": "example.net",
  1348. "port": ""
  1349. }
  1350. },
  1351. {
  1352. "comment": "Default port number is removed",
  1353. "href": "https://example.net:4433",
  1354. "new_value": "443",
  1355. "expected": {
  1356. "href": "https://example.net/",
  1357. "host": "example.net",
  1358. "hostname": "example.net",
  1359. "port": ""
  1360. }
  1361. },
  1362. {
  1363. "comment": "Default port number is only removed for the relevant scheme",
  1364. "href": "https://example.net",
  1365. "new_value": "80",
  1366. "expected": {
  1367. "href": "https://example.net:80/",
  1368. "host": "example.net:80",
  1369. "hostname": "example.net",
  1370. "port": "80"
  1371. }
  1372. },
  1373. {
  1374. "comment": "Stuff after a / delimiter is ignored",
  1375. "href": "http://example.net/path",
  1376. "new_value": "8080/stuff",
  1377. "expected": {
  1378. "href": "http://example.net:8080/path",
  1379. "host": "example.net:8080",
  1380. "hostname": "example.net",
  1381. "port": "8080"
  1382. }
  1383. },
  1384. {
  1385. "comment": "Stuff after a ? delimiter is ignored",
  1386. "href": "http://example.net/path",
  1387. "new_value": "8080?stuff",
  1388. "expected": {
  1389. "href": "http://example.net:8080/path",
  1390. "host": "example.net:8080",
  1391. "hostname": "example.net",
  1392. "port": "8080"
  1393. }
  1394. },
  1395. {
  1396. "comment": "Stuff after a # delimiter is ignored",
  1397. "href": "http://example.net/path",
  1398. "new_value": "8080#stuff",
  1399. "expected": {
  1400. "href": "http://example.net:8080/path",
  1401. "host": "example.net:8080",
  1402. "hostname": "example.net",
  1403. "port": "8080"
  1404. }
  1405. },
  1406. {
  1407. "comment": "Stuff after a \\ delimiter is ignored for special schemes",
  1408. "href": "http://example.net/path",
  1409. "new_value": "8080\\stuff",
  1410. "expected": {
  1411. "href": "http://example.net:8080/path",
  1412. "host": "example.net:8080",
  1413. "hostname": "example.net",
  1414. "port": "8080"
  1415. }
  1416. },
  1417. {
  1418. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  1419. "href": "view-source+http://example.net/path",
  1420. "new_value": "8080stuff2",
  1421. "expected": {
  1422. "href": "view-source+http://example.net:8080/path",
  1423. "host": "example.net:8080",
  1424. "hostname": "example.net",
  1425. "port": "8080"
  1426. }
  1427. },
  1428. {
  1429. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  1430. "href": "http://example.net/path",
  1431. "new_value": "8080stuff2",
  1432. "expected": {
  1433. "href": "http://example.net:8080/path",
  1434. "host": "example.net:8080",
  1435. "hostname": "example.net",
  1436. "port": "8080"
  1437. }
  1438. },
  1439. {
  1440. "comment": "Anything other than ASCII digit stops the port parser in a setter but is not an error",
  1441. "href": "http://example.net/path",
  1442. "new_value": "8080+2",
  1443. "expected": {
  1444. "href": "http://example.net:8080/path",
  1445. "host": "example.net:8080",
  1446. "hostname": "example.net",
  1447. "port": "8080"
  1448. }
  1449. },
  1450. {
  1451. "comment": "Port numbers are 16 bit integers",
  1452. "href": "http://example.net/path",
  1453. "new_value": "65535",
  1454. "expected": {
  1455. "href": "http://example.net:65535/path",
  1456. "host": "example.net:65535",
  1457. "hostname": "example.net",
  1458. "port": "65535"
  1459. }
  1460. },
  1461. {
  1462. "comment": "Port numbers are 16 bit integers, overflowing is an error",
  1463. "href": "http://example.net:8080/path",
  1464. "new_value": "65536",
  1465. "expected": {
  1466. "href": "http://example.net:8080/path",
  1467. "host": "example.net:8080",
  1468. "hostname": "example.net",
  1469. "port": "8080"
  1470. }
  1471. },
  1472. {
  1473. "comment": "Port numbers are 16 bit integers, overflowing is an error",
  1474. "href": "non-special://example.net:8080/path",
  1475. "new_value": "65536",
  1476. "expected": {
  1477. "href": "non-special://example.net:8080/path",
  1478. "host": "example.net:8080",
  1479. "hostname": "example.net",
  1480. "port": "8080"
  1481. }
  1482. },
  1483. {
  1484. "href": "file://test/",
  1485. "new_value": "12",
  1486. "expected": {
  1487. "href": "file://test/",
  1488. "port": ""
  1489. }
  1490. },
  1491. {
  1492. "href": "file://localhost/",
  1493. "new_value": "12",
  1494. "expected": {
  1495. "href": "file:///",
  1496. "port": ""
  1497. }
  1498. },
  1499. {
  1500. "href": "non-base:value",
  1501. "new_value": "12",
  1502. "expected": {
  1503. "href": "non-base:value",
  1504. "port": ""
  1505. }
  1506. },
  1507. {
  1508. "href": "sc:///",
  1509. "new_value": "12",
  1510. "expected": {
  1511. "href": "sc:///",
  1512. "port": ""
  1513. }
  1514. },
  1515. {
  1516. "href": "sc://x/",
  1517. "new_value": "12",
  1518. "expected": {
  1519. "href": "sc://x:12/",
  1520. "port": "12"
  1521. }
  1522. },
  1523. {
  1524. "href": "javascript://x/",
  1525. "new_value": "12",
  1526. "expected": {
  1527. "href": "javascript://x:12/",
  1528. "port": "12"
  1529. }
  1530. }
  1531. ],
  1532. "pathname": [
  1533. {
  1534. "comment": "Cannot-be-a-base don’t have a path",
  1535. "href": "mailto:me@example.net",
  1536. "new_value": "/foo",
  1537. "expected": {
  1538. "href": "mailto:me@example.net",
  1539. "pathname": "me@example.net"
  1540. }
  1541. },
  1542. {
  1543. "href": "unix:/run/foo.socket?timeout=10",
  1544. "new_value": "/var/log/../run/bar.socket",
  1545. "expected": {
  1546. "href": "unix:/var/run/bar.socket?timeout=10",
  1547. "pathname": "/var/run/bar.socket"
  1548. }
  1549. },
  1550. {
  1551. "href": "https://example.net#nav",
  1552. "new_value": "home",
  1553. "expected": {
  1554. "href": "https://example.net/home#nav",
  1555. "pathname": "/home"
  1556. }
  1557. },
  1558. {
  1559. "href": "https://example.net#nav",
  1560. "new_value": "../home",
  1561. "expected": {
  1562. "href": "https://example.net/home#nav",
  1563. "pathname": "/home"
  1564. }
  1565. },
  1566. {
  1567. "comment": "\\ is a segment delimiter for 'special' URLs",
  1568. "href": "http://example.net/home?lang=fr#nav",
  1569. "new_value": "\\a\\%2E\\b\\%2e.\\c",
  1570. "expected": {
  1571. "href": "http://example.net/a/c?lang=fr#nav",
  1572. "pathname": "/a/c"
  1573. }
  1574. },
  1575. {
  1576. "comment": "\\ is *not* a segment delimiter for non-'special' URLs",
  1577. "href": "view-source+http://example.net/home?lang=fr#nav",
  1578. "new_value": "\\a\\%2E\\b\\%2e.\\c",
  1579. "expected": {
  1580. "href": "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav",
  1581. "pathname": "/\\a\\%2E\\b\\%2e.\\c"
  1582. }
  1583. },
  1584. {
  1585. "comment": "UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.",
  1586. "href": "a:/",
  1587. "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
  1588. "expected": {
  1589. "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",
  1590. "pathname": "/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9"
  1591. }
  1592. },
  1593. {
  1594. "comment": "Bytes already percent-encoded are left as-is, including %2E outside dotted segments.",
  1595. "href": "http://example.net",
  1596. "new_value": "%2e%2E%c3%89té",
  1597. "expected": {
  1598. "href": "http://example.net/%2e%2E%c3%89t%C3%A9",
  1599. "pathname": "/%2e%2E%c3%89t%C3%A9"
  1600. }
  1601. },
  1602. {
  1603. "comment": "? needs to be encoded",
  1604. "href": "http://example.net",
  1605. "new_value": "?",
  1606. "expected": {
  1607. "href": "http://example.net/%3F",
  1608. "pathname": "/%3F"
  1609. }
  1610. },
  1611. {
  1612. "comment": "# needs to be encoded",
  1613. "href": "http://example.net",
  1614. "new_value": "#",
  1615. "expected": {
  1616. "href": "http://example.net/%23",
  1617. "pathname": "/%23"
  1618. }
  1619. },
  1620. {
  1621. "comment": "? needs to be encoded, non-special scheme",
  1622. "href": "sc://example.net",
  1623. "new_value": "?",
  1624. "expected": {
  1625. "href": "sc://example.net/%3F",
  1626. "pathname": "/%3F"
  1627. }
  1628. },
  1629. {
  1630. "comment": "# needs to be encoded, non-special scheme",
  1631. "href": "sc://example.net",
  1632. "new_value": "#",
  1633. "expected": {
  1634. "href": "sc://example.net/%23",
  1635. "pathname": "/%23"
  1636. }
  1637. },
  1638. {
  1639. "comment": "File URLs and (back)slashes",
  1640. "href": "file://monkey/",
  1641. "new_value": "\\\\",
  1642. "expected": {
  1643. "href": "file://monkey/",
  1644. "pathname": "/"
  1645. }
  1646. },
  1647. {
  1648. "comment": "File URLs and (back)slashes",
  1649. "href": "file:///unicorn",
  1650. "new_value": "//\\/",
  1651. "expected": {
  1652. "href": "file:///",
  1653. "pathname": "/"
  1654. }
  1655. },
  1656. {
  1657. "comment": "File URLs and (back)slashes",
  1658. "href": "file:///unicorn",
  1659. "new_value": "//monkey/..//",
  1660. "expected": {
  1661. "href": "file:///",
  1662. "pathname": "/"
  1663. }
  1664. }
  1665. ],
  1666. "search": [
  1667. {
  1668. "href": "https://example.net#nav",
  1669. "new_value": "lang=fr",
  1670. "expected": {
  1671. "href": "https://example.net/?lang=fr#nav",
  1672. "search": "?lang=fr"
  1673. }
  1674. },
  1675. {
  1676. "href": "https://example.net?lang=en-US#nav",
  1677. "new_value": "lang=fr",
  1678. "expected": {
  1679. "href": "https://example.net/?lang=fr#nav",
  1680. "search": "?lang=fr"
  1681. }
  1682. },
  1683. {
  1684. "href": "https://example.net?lang=en-US#nav",
  1685. "new_value": "?lang=fr",
  1686. "expected": {
  1687. "href": "https://example.net/?lang=fr#nav",
  1688. "search": "?lang=fr"
  1689. }
  1690. },
  1691. {
  1692. "href": "https://example.net?lang=en-US#nav",
  1693. "new_value": "??lang=fr",
  1694. "expected": {
  1695. "href": "https://example.net/??lang=fr#nav",
  1696. "search": "??lang=fr"
  1697. }
  1698. },
  1699. {
  1700. "href": "https://example.net?lang=en-US#nav",
  1701. "new_value": "?",
  1702. "expected": {
  1703. "href": "https://example.net/?#nav",
  1704. "search": ""
  1705. }
  1706. },
  1707. {
  1708. "href": "https://example.net?lang=en-US#nav",
  1709. "new_value": "",
  1710. "expected": {
  1711. "href": "https://example.net/#nav",
  1712. "search": ""
  1713. }
  1714. },
  1715. {
  1716. "href": "https://example.net?lang=en-US",
  1717. "new_value": "",
  1718. "expected": {
  1719. "href": "https://example.net/",
  1720. "search": ""
  1721. }
  1722. },
  1723. {
  1724. "href": "https://example.net",
  1725. "new_value": "",
  1726. "expected": {
  1727. "href": "https://example.net/",
  1728. "search": ""
  1729. }
  1730. },
  1731. {
  1732. "comment": "UTF-8 percent encoding with the query encode set. Tabs and newlines are removed.",
  1733. "href": "a:/",
  1734. "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
  1735. "expected": {
  1736. "href": "a:/?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9",
  1737. "search": "?%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9"
  1738. }
  1739. },
  1740. {
  1741. "comment": "Bytes already percent-encoded are left as-is",
  1742. "href": "http://example.net",
  1743. "new_value": "%c3%89té",
  1744. "expected": {
  1745. "href": "http://example.net/?%c3%89t%C3%A9",
  1746. "search": "?%c3%89t%C3%A9"
  1747. }
  1748. }
  1749. ],
  1750. "hash": [
  1751. {
  1752. "href": "https://example.net",
  1753. "new_value": "main",
  1754. "expected": {
  1755. "href": "https://example.net/#main",
  1756. "hash": "#main"
  1757. }
  1758. },
  1759. {
  1760. "href": "https://example.net#nav",
  1761. "new_value": "main",
  1762. "expected": {
  1763. "href": "https://example.net/#main",
  1764. "hash": "#main"
  1765. }
  1766. },
  1767. {
  1768. "href": "https://example.net?lang=en-US",
  1769. "new_value": "##nav",
  1770. "expected": {
  1771. "href": "https://example.net/?lang=en-US##nav",
  1772. "hash": "##nav"
  1773. }
  1774. },
  1775. {
  1776. "href": "https://example.net?lang=en-US#nav",
  1777. "new_value": "#main",
  1778. "expected": {
  1779. "href": "https://example.net/?lang=en-US#main",
  1780. "hash": "#main"
  1781. }
  1782. },
  1783. {
  1784. "href": "https://example.net?lang=en-US#nav",
  1785. "new_value": "#",
  1786. "expected": {
  1787. "href": "https://example.net/?lang=en-US#",
  1788. "hash": ""
  1789. }
  1790. },
  1791. {
  1792. "href": "https://example.net?lang=en-US#nav",
  1793. "new_value": "",
  1794. "expected": {
  1795. "href": "https://example.net/?lang=en-US",
  1796. "hash": ""
  1797. }
  1798. },
  1799. {
  1800. "href": "http://example.net",
  1801. "new_value": "#foo bar",
  1802. "expected": {
  1803. "href": "http://example.net/#foo%20bar",
  1804. "hash": "#foo%20bar"
  1805. }
  1806. },
  1807. {
  1808. "href": "http://example.net",
  1809. "new_value": "#foo\"bar",
  1810. "expected": {
  1811. "href": "http://example.net/#foo%22bar",
  1812. "hash": "#foo%22bar"
  1813. }
  1814. },
  1815. {
  1816. "href": "http://example.net",
  1817. "new_value": "#foo<bar",
  1818. "expected": {
  1819. "href": "http://example.net/#foo%3Cbar",
  1820. "hash": "#foo%3Cbar"
  1821. }
  1822. },
  1823. {
  1824. "href": "http://example.net",
  1825. "new_value": "#foo>bar",
  1826. "expected": {
  1827. "href": "http://example.net/#foo%3Ebar",
  1828. "hash": "#foo%3Ebar"
  1829. }
  1830. },
  1831. {
  1832. "href": "http://example.net",
  1833. "new_value": "#foo`bar",
  1834. "expected": {
  1835. "href": "http://example.net/#foo%60bar",
  1836. "hash": "#foo%60bar"
  1837. }
  1838. },
  1839. {
  1840. "comment": "Simple percent-encoding; nuls, tabs, and newlines are removed",
  1841. "href": "a:/",
  1842. "new_value": "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
  1843. "expected": {
  1844. "href": "a:/#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9",
  1845. "hash": "#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9"
  1846. }
  1847. },
  1848. {
  1849. "comment": "Bytes already percent-encoded are left as-is",
  1850. "href": "http://example.net",
  1851. "new_value": "%c3%89té",
  1852. "expected": {
  1853. "href": "http://example.net/#%c3%89t%C3%A9",
  1854. "hash": "#%c3%89t%C3%A9"
  1855. }
  1856. },
  1857. {
  1858. "href": "javascript:alert(1)",
  1859. "new_value": "castle",
  1860. "expected": {
  1861. "href": "javascript:alert(1)#castle",
  1862. "hash": "#castle"
  1863. }
  1864. }
  1865. ]
  1866. }