|
|
|
|
@ -73,3 +73,137 @@ function env_default() { |
|
|
|
|
env | grep -q "^$1=" && return 0 |
|
|
|
|
export "$1=$2" && return 3 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Required for $langinfo |
|
|
|
|
zmodload zsh/langinfo |
|
|
|
|
|
|
|
|
|
# URL-encode a string |
|
|
|
|
# |
|
|
|
|
# Encodes a string using RFC 2396 URL-encoding (%-escaped). |
|
|
|
|
# See: https://www.ietf.org/rfc/rfc2396.txt |
|
|
|
|
# |
|
|
|
|
# By default, reserved characters and unreserved "mark" characters are |
|
|
|
|
# not escaped by this function. This allows the common usage of passing |
|
|
|
|
# an entire URL in, and encoding just special characters in it, with |
|
|
|
|
# the expectation that reserved and mark characters are used appropriately. |
|
|
|
|
# The -r and -m options turn on escaping of the reserved and mark characters, |
|
|
|
|
# respectively, which allows arbitrary strings to be fully escaped for |
|
|
|
|
# embedding inside URLs, where reserved characters might be misinterpreted. |
|
|
|
|
# |
|
|
|
|
# Prints the encoded string on stdout. |
|
|
|
|
# Returns nonzero if encoding failed. |
|
|
|
|
# |
|
|
|
|
# Usage: |
|
|
|
|
# omz_urlencode [-r] [-m] <string> |
|
|
|
|
# |
|
|
|
|
# -r causes reserved characters (;/?:@&=+$,) to be escaped |
|
|
|
|
# |
|
|
|
|
# -m causes "mark" characters (_.!~*''()-) to be escaped |
|
|
|
|
# |
|
|
|
|
# -P causes spaces to be encoded as '%20' instead of '+' |
|
|
|
|
function omz_urlencode() { |
|
|
|
|
emulate -L zsh |
|
|
|
|
zparseopts -D -E -a opts r m P |
|
|
|
|
|
|
|
|
|
local in_str=$1 |
|
|
|
|
local url_str="" |
|
|
|
|
local spaces_as_plus |
|
|
|
|
if [[ -z $opts[(r)-P] ]]; then spaces_as_plus=1; fi |
|
|
|
|
local str="$in_str" |
|
|
|
|
|
|
|
|
|
# URLs must use UTF-8 encoding; convert str to UTF-8 if required |
|
|
|
|
local encoding=$langinfo[CODESET] |
|
|
|
|
local safe_encodings |
|
|
|
|
safe_encodings=(UTF-8 utf8 US-ASCII) |
|
|
|
|
if [[ -z ${safe_encodings[(r)$encoding]} ]]; then |
|
|
|
|
str=$(echo -E "$str" | iconv -f $encoding -t UTF-8) |
|
|
|
|
if [[ $? != 0 ]]; then |
|
|
|
|
echo "Error converting string from $encoding to UTF-8" >&2 |
|
|
|
|
return 1 |
|
|
|
|
fi |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
# Use LC_CTYPE=C to process text byte-by-byte |
|
|
|
|
local i byte ord LC_ALL=C |
|
|
|
|
export LC_ALL |
|
|
|
|
local reserved=';/?:@&=+$,' |
|
|
|
|
local mark='_.!~*''()-' |
|
|
|
|
local dont_escape="[A-Za-z0-9" |
|
|
|
|
if [[ -z $opts[(r)-r] ]]; then |
|
|
|
|
dont_escape+=$reserved |
|
|
|
|
fi |
|
|
|
|
# $mark must be last because of the "-" |
|
|
|
|
if [[ -z $opts[(r)-m] ]]; then |
|
|
|
|
dont_escape+=$mark |
|
|
|
|
fi |
|
|
|
|
dont_escape+="]" |
|
|
|
|
|
|
|
|
|
# Implemented to use a single printf call and avoid subshells in the loop, |
|
|
|
|
# for performance (primarily on Windows). |
|
|
|
|
local url_str="" |
|
|
|
|
for (( i = 1; i <= ${#str}; ++i )); do |
|
|
|
|
byte="$str[i]" |
|
|
|
|
if [[ "$byte" =~ "$dont_escape" ]]; then |
|
|
|
|
url_str+="$byte" |
|
|
|
|
else |
|
|
|
|
if [[ "$byte" == " " && -n $spaces_as_plus ]]; then |
|
|
|
|
url_str+="+" |
|
|
|
|
else |
|
|
|
|
ord=$(( [##16] #byte )) |
|
|
|
|
url_str+="%$ord" |
|
|
|
|
fi |
|
|
|
|
fi |
|
|
|
|
done |
|
|
|
|
echo -E "$url_str" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# URL-decode a string |
|
|
|
|
# |
|
|
|
|
# Decodes a RFC 2396 URL-encoded (%-escaped) string. |
|
|
|
|
# This decodes the '+' and '%' escapes in the input string, and leaves |
|
|
|
|
# other characters unchanged. Does not enforce that the input is a |
|
|
|
|
# valid URL-encoded string. This is a convenience to allow callers to |
|
|
|
|
# pass in a full URL or similar strings and decode them for human |
|
|
|
|
# presentation. |
|
|
|
|
# |
|
|
|
|
# Outputs the encoded string on stdout. |
|
|
|
|
# Returns nonzero if encoding failed. |
|
|
|
|
# |
|
|
|
|
# Usage: |
|
|
|
|
# omz_urldecode <urlstring> - prints decoded string followed by a newline |
|
|
|
|
function omz_urldecode { |
|
|
|
|
emulate -L zsh |
|
|
|
|
local encoded_url=$1 |
|
|
|
|
|
|
|
|
|
echo -e input $1 |
|
|
|
|
# Work bytewise, since URLs escape UTF-8 octets |
|
|
|
|
local caller_encoding=$langinfo[CODESET] |
|
|
|
|
local LC_ALL=C |
|
|
|
|
export LC_ALL |
|
|
|
|
|
|
|
|
|
# Change + back to ' ' |
|
|
|
|
local tmp=${encoded_url:gs/+/ /} |
|
|
|
|
# Protect other escapes to pass through the printf unchanged |
|
|
|
|
tmp=${tmp:gs/\\/\\\\/} |
|
|
|
|
# Handle %-escapes by turning them into `\xXX` printf escapes |
|
|
|
|
tmp=${tmp:gs/%/\\x/} |
|
|
|
|
echo -E "before decode $tmp" |
|
|
|
|
local decoded |
|
|
|
|
eval "decoded=\$'$tmp'" |
|
|
|
|
|
|
|
|
|
# Now we have a UTF-8 encoded string in the variable. We need to re-encode |
|
|
|
|
# it if caller is in a non-UTF-8 locale. |
|
|
|
|
local safe_encodings |
|
|
|
|
safe_encodings=(UTF-8 utf8 US-ASCII) |
|
|
|
|
if [[ -z ${safe_encodings[(r)$caller_encoding]} ]]; then |
|
|
|
|
decoded=$(echo -E "$decoded" | iconv -f UTF-8 -t $caller_encoding) |
|
|
|
|
if [[ $? != 0 ]]; then |
|
|
|
|
echo "Error converting string from UTF-8 to $caller_encoding" >&2 |
|
|
|
|
return 1 |
|
|
|
|
fi |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
echo -E "$decoded" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|