From 6455a7f85522fd319caa8cb7cffa93b4ee9ca4b9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Wed, 28 Apr 2021 10:58:27 +0200 Subject: [PATCH] Squashed 'cgilite/' changes from 13c2995..c207699 c207699 bugfix: fix error when reading literal "+" char from storage e7e354d basic print styles 4b913ff set foreground color where background color is set 49b4c44 remove obsolte escape functions 47a1cf6 introduce functions for cookie based cryptographically signed session variables e3e5c0d introduce simple DBM module 8070ac9 use debug function for error output git-subtree-dir: cgilite git-subtree-split: c207699d7f39ce4bf96139e25da61e13cb94be4c --- common.css | 21 +++++++-- session.sh | 17 +++++++ storage.sh | 128 ++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 137 insertions(+), 29 deletions(-) diff --git a/common.css b/common.css index 9e72c16..f9b17ad 100644 --- a/common.css +++ b/common.css @@ -60,7 +60,7 @@ h2 { font-size: 1.125em; } select, input, button, textarea, a.button { display: inline-block; - background-color: #FFF; + color: #000; background-color: #FFF; border: .5pt solid; padding: .25em .75em; vertical-align: text-bottom; @@ -87,6 +87,20 @@ input + label { margin-left: .375em; } +@media print { + @page { margin: 20mm; } + + h1 { text-align: center; } + + h1, h2, h3, h4, h5, h6, form legend { + page-break-inside: avoid; + page-break-after: avoid; + page-break-before: auto; + } + li { page-break-inside: avoid; } + th, dt { page-break-after: avoid; } +} + /* ======= End Generic Styles ======= */ /* ======= Common Styles ======= */ @@ -97,8 +111,7 @@ input + label { bottom: -100%; left: 50%; transform: translate(-50%, 0); content: attr(tooltip); padding: .5em; - background-color: #FFC; - color: #000; + color: #000; background-color: #FFC; border: .5pt solid; z-index: 1; } @@ -107,7 +120,7 @@ input[type=radio].tab { display: none; } input[type=radio].tab + label { display: table-cell; padding: .5em 1em; - background-color: #EEE; + color: #000; background-color: #EEE; border: .5pt solid; } input[type=radio].tab:checked + label { diff --git a/session.sh b/session.sh index 93cc2f4..b52ac0a 100755 --- a/session.sh +++ b/session.sh @@ -86,3 +86,20 @@ update_session(){ SESSION_KEY="$(update_session)" SET_COOKIE 0 session="$SESSION_KEY" Path=/ SameSite=Strict HttpOnly SESSION_ID="${SESSION_KEY%% *}" + +SESSION_BIND() { + local key="$1" value="$2" + SET_COOKIE session "$key"="${value} $(session_mac "$value" "$SESSION_ID")" +} + +SESSION_VAR() { + local key="$1" + local value sig + value="$(COOKIE "$key")" + sig="${value##* }" value="${value% *}" + if [ "$sig" = "$(session_mac "$value" "$SESSION_ID")" ]; then + printf %s\\n "$value" + else + return 1 + fi +} diff --git a/storage.sh b/storage.sh index 7f70e64..355bd56 100755 --- a/storage.sh +++ b/storage.sh @@ -29,18 +29,18 @@ LOCK(){ lock="${1}.lock" timeout="${2-20}" if [ \! -w "${lock%/*}" ] || [ -e "$lock" -a \! -d "$lock" ]; then - printf 'Impossible to get lock: %s\n' "$lock" >&2 + debug "Impossible to get lock: $lock" return 1 fi while ! mkdir "$lock" 2>&-; do block="$(cat "$lock/pid" || printf 1)" if ! { ps -eo pid |grep -qwF "$block"; }; then - printf 'Overriding stale lock: %s\n' "$lock" >&2 + debug "Overriding stale lock: $lock" break fi if [ $timeout -le 0 ]; then - printf 'Timeout while trying to get lock: %s\n' "$lock" >&2 + debug "Timeout while trying to get lock: $lock" return 1 fi timeout=$((timeout - 1)) @@ -56,31 +56,22 @@ RELEASE(){ if [ "$(cat "$lock/pid")" = "$$" ]; then rm "$lock/pid" if ! rmdir "$lock"; then - printf 'Cannot remove tainted lock: %s\n' "$lock" >&2 + debug "Cannot remove tainted lock: $lock" printf '%i\n' $$ >"${lock}/pid" return 1 fi return 0 else - printf 'Refusing to release foreign lock: %s\n' "$lock" >&2 + debug "Refusing to release foreign lock: $lock" return 1 fi } -STRING=' - s;\\;\\\\;g; - s;\n;\\n;g; - s;\t;\\t;g; - s;\r;\\r;g; - s;\+;\\+;g; - s; ;+;g; -' - -STRING_OLD(){ - { [ $# -eq 0 ] && cat || printf %s "$*"; } \ - | sed -E ':X; $!{N;bX;}'"$STRING" -} - +# STRING=' +# s;\\;\\\\;g; s;\t;\\t;g; +# s;\n;\\n;g; s;\r;\\r;g; +# s;\+;\\+;g; s; ;+;g; +# ' STRING(){ local in out='' [ $# -gt 0 ] && in="$*" || in="$(cat)" @@ -96,7 +87,6 @@ STRING(){ printf '%s' "$out" } - UNSTRING=' :UNSTRING_X s;((^|[^\\])(\\\\)*)\\n;\1\n;g; @@ -107,10 +97,6 @@ UNSTRING=' s;((^|[^\\])(\\\\)*)\\\+;\1+;g; s;\\\\;\\;g; ' -UNSTRING_OLD(){ - { [ $# -eq 0 ] && cat || printf %s "$*"; } \ - | sed -E "$UNSTRING" -} UNSTRING(){ local in out='' [ $# -gt 0 ] && in="$*" || in="$(cat)" @@ -119,7 +105,7 @@ UNSTRING(){ \\n*) out="${out}${BR}"; in="${in#\\n}" ;; \\r*) out="${out}${CR}"; in="${in#\\r}" ;; \\t*) out="${out} "; in="${in#\\t}" ;; - \\+) out="${out}+"; in="${in#\\+}" ;; + \\+*) out="${out}+"; in="${in#\\+}" ;; +*) out="${out} "; in="${in#+}" ;; \\*) in="${in#\\}" ;; *) out="${out}${in%%[\\+]*}"; in="${in#"${in%%[\\+]*}"}" ;; @@ -127,3 +113,95 @@ UNSTRING(){ printf '%s' "$out" } +DBM() { + local file="$1" cmd="$2" + local k v key value + shift 2; + + case "$cmd" in + check|contains) + key="$(STRING "$1")" + while read -r k v; do if [ "$k" = "$key" ]; then + return 0 + fi; done <"$file" 2>&- + return 1 + ;; + get) + key="$(STRING "$1")" + while read -r k v; do if [ "$k" = "$key" ]; then + UNSTRING "$v" + return 0 + fi; done <"$file" 2>&- + return 1 + ;; + set|store) + key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + { while read -r k v; do + [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + printf '%s\t%s\n' "$key" "$value" + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + add|insert) + k="$1" key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + if DBM "$file" check "$k"; then + RELEASE "$file" + return 1 + else + printf '%s\t%s\n' "$key" "$value" >>"${file}" + RELEASE "$file" + return 0 + fi + ;; + update|replace) + k="$1" key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + if ! DBM check "$k"; then + RELEASE "$file" + return 1 + fi + { while read -r k v; do + [ "$k" = "$key" ] \ + && printf '%s\t%s\n' "$key" "$value" \ + || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + append) + key="$(STRING "$1")" value="$(STRING "$2")" + LOCK "$file" || return 1 + if ! DBM check "$1"; then + RELEASE "$file" + return 1 + fi + { while read -r k v; do + [ "$k" = "$key" ] \ + && printf '%s\t%s\n' "$key" "$v$value" \ + || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + delete|remove) + key="$(STRING "$1")" + LOCK "$file" || return 1 + { while read -r k v; do + [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v" + done <"$file" 2>&- + } >"${file}.$$.tmp" + mv "${file}.$$.tmp" "${file}" + RELEASE "$file" + return 0 + ;; + esac +} -- 2.39.2