| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 | "use strict";const { utf8Encode, utf8DecodeWithoutBOM } = require("./encoding");const { percentDecodeBytes, utf8PercentEncodeString, isURLEncodedPercentEncode } = require("./percent-encoding");function p(char) {  return char.codePointAt(0);}// https://url.spec.whatwg.org/#concept-urlencoded-parserfunction parseUrlencoded(input) {  const sequences = strictlySplitByteSequence(input, p("&"));  const output = [];  for (const bytes of sequences) {    if (bytes.length === 0) {      continue;    }    let name, value;    const indexOfEqual = bytes.indexOf(p("="));    if (indexOfEqual >= 0) {      name = bytes.slice(0, indexOfEqual);      value = bytes.slice(indexOfEqual + 1);    } else {      name = bytes;      value = new Uint8Array(0);    }    name = replaceByteInByteSequence(name, 0x2B, 0x20);    value = replaceByteInByteSequence(value, 0x2B, 0x20);    const nameString = utf8DecodeWithoutBOM(percentDecodeBytes(name));    const valueString = utf8DecodeWithoutBOM(percentDecodeBytes(value));    output.push([nameString, valueString]);  }  return output;}// https://url.spec.whatwg.org/#concept-urlencoded-string-parserfunction parseUrlencodedString(input) {  return parseUrlencoded(utf8Encode(input));}// https://url.spec.whatwg.org/#concept-urlencoded-serializerfunction serializeUrlencoded(tuples, encodingOverride = undefined) {  let encoding = "utf-8";  if (encodingOverride !== undefined) {    // TODO "get the output encoding", i.e. handle encoding labels vs. names.    encoding = encodingOverride;  }  let output = "";  for (const [i, tuple] of tuples.entries()) {    // TODO: handle encoding override    const name = utf8PercentEncodeString(tuple[0], isURLEncodedPercentEncode, true);    let value = tuple[1];    if (tuple.length > 2 && tuple[2] !== undefined) {      if (tuple[2] === "hidden" && name === "_charset_") {        value = encoding;      } else if (tuple[2] === "file") {        // value is a File object        value = value.name;      }    }    value = utf8PercentEncodeString(value, isURLEncodedPercentEncode, true);    if (i !== 0) {      output += "&";    }    output += `${name}=${value}`;  }  return output;}function strictlySplitByteSequence(buf, cp) {  const list = [];  let last = 0;  let i = buf.indexOf(cp);  while (i >= 0) {    list.push(buf.slice(last, i));    last = i + 1;    i = buf.indexOf(cp, last);  }  if (last !== buf.length) {    list.push(buf.slice(last));  }  return list;}function replaceByteInByteSequence(buf, from, to) {  let i = buf.indexOf(from);  while (i >= 0) {    buf[i] = to;    i = buf.indexOf(from, i + 1);  }  return buf;}module.exports = {  parseUrlencodedString,  serializeUrlencoded};
 |