strings: add escapeQuery for url encoding

This commit is contained in:
Patrick Widmer 2023-03-02 21:41:51 +01:00
parent 55fc05fb8c
commit 7089294f10
4 changed files with 32 additions and 5 deletions

View file

@ -1,4 +1,7 @@
{ " " = 32; { "\t" = 9;
"\n" = 10;
"\r" = 13;
" " = 32;
"!" = 33; "!" = 33;
"\"" = 34; "\"" = 34;
"#" = 35; "#" = 35;

View file

@ -100,7 +100,7 @@ let
escapeShellArg escapeShellArgs escapeShellArg escapeShellArgs
isStorePath isStringLike isStorePath isStringLike
isValidPosixName toShellVar toShellVars isValidPosixName toShellVar toShellVars
escapeRegex escapeXML replaceChars lowerChars escapeRegex escapeURL escapeXML replaceChars lowerChars
upperChars toLower toUpper addContextFrom splitString upperChars toLower toUpper addContextFrom splitString
removePrefix removeSuffix versionOlder versionAtLeast removePrefix removeSuffix versionOlder versionAtLeast
getName getVersion getName getVersion

View file

@ -34,6 +34,8 @@ rec {
unsafeDiscardStringContext unsafeDiscardStringContext
; ;
asciiTable = import ./ascii-table.nix;
/* Concatenate a list of strings. /* Concatenate a list of strings.
Type: concatStrings :: [string] -> string Type: concatStrings :: [string] -> string
@ -327,9 +329,7 @@ rec {
=> 40 => 40
*/ */
charToInt = let charToInt = c: builtins.getAttr c asciiTable;
table = import ./ascii-table.nix;
in c: builtins.getAttr c table;
/* Escape occurrence of the elements of `list` in `string` by /* Escape occurrence of the elements of `list` in `string` by
prefixing it with a backslash. prefixing it with a backslash.
@ -355,6 +355,21 @@ rec {
*/ */
escapeC = list: replaceStrings list (map (c: "\\x${ toLower (lib.toHexString (charToInt c))}") list); escapeC = list: replaceStrings list (map (c: "\\x${ toLower (lib.toHexString (charToInt c))}") list);
/* Escape the string so it can be safely placed inside a URL
query.
Type: escapeURL :: string -> string
Example:
escapeURL "foo/bar baz"
=> "foo%2Fbar%20baz"
*/
escapeURL = let
unreserved = [ "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "-" "_" "." "~" ];
toEscape = builtins.removeAttrs asciiTable unreserved;
in
replaceStrings (builtins.attrNames toEscape) (lib.mapAttrsToList (_: c: "%${fixedWidthString 2 "0" (lib.toHexString c)}") toEscape);
/* Quote string to be used safely within the Bourne shell. /* Quote string to be used safely within the Bourne shell.
Type: escapeShellArg :: string -> string Type: escapeShellArg :: string -> string

View file

@ -347,6 +347,15 @@ runTests {
expected = "Hello\\x20World"; expected = "Hello\\x20World";
}; };
testEscapeURL = testAllTrue [
("" == strings.escapeURL "")
("Hello" == strings.escapeURL "Hello")
("Hello%20World" == strings.escapeURL "Hello World")
("Hello%2FWorld" == strings.escapeURL "Hello/World")
("42%25" == strings.escapeURL "42%")
("%20%3F%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%09%3A%2F%40%24%27%28%29%2A%2C%3B" == strings.escapeURL " ?&=#+%!<>#\"{}|\\^[]`\t:/@$'()*,;")
];
testToInt = testAllTrue [ testToInt = testAllTrue [
# Naive # Naive
(123 == toInt "123") (123 == toInt "123")