Skip to content

Commit dd778bf

Browse files
committed
Remove hard dependency on xxd which can be onerous, fall back to printf or perl instead
Remove hard dependency on `xxd` which is often a heavy requirement because it is only available with Vim on some platforms. Fall back to using `printf` (provided it has full %b support) or `perl` when either of these are available, and only require that `xxd` be installed and available when that is the only viable option. Adapted from #181. Thanks @andreineculau!
1 parent f88979c commit dd778bf

File tree

4 files changed

+32
-9
lines changed

4 files changed

+32
-9
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ system, you must also run the `--upgrade` command in each repository:
5353

5454
### Changed
5555

56+
- Remove hard dependency on `xxd` which is often a heavy requirement because it
57+
is only available with Vim on some platforms. Fall back to `printf` with full
58+
%b support or `perl` when either of these are available, and only require
59+
`xxd` when it is the only viable option (#181)
5660
- Prevent global options set in `GREP_OPTIONS` enviroment variable from
5761
breaking transcrypt's use of grep (#166)
5862
- If `CDPATH` is set then cd will print the path (#156)

INSTALL.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ The requirements to run transcrypt are minimal:
66
- Git
77
- OpenSSL
88
- `column` command (on Ubuntu/Debian install `bsdmainutils`)
9-
- `xxd` command if using OpenSSL version 3
10-
(on Ubuntu/Debian is included with `vim`)
9+
- if using OpenSSL 3+ one of: `xxd` (on Ubuntu/Debian is included with `vim`)
10+
or `printf` command (with %b directive) or `perl`
1111

1212
...and optionally:
1313

@@ -74,4 +74,3 @@ collection:
7474
or via the packages system:
7575

7676
# `pkg install -y security/transcrypt`
77-

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ The requirements to run transcrypt are minimal:
5656
- Git
5757
- OpenSSL
5858
- `column` and `hexdump` commands (on Ubuntu/Debian install `bsdmainutils`)
59-
- `xxd` command if using OpenSSL version 3
60-
(on Ubuntu/Debian is included with `vim`)
59+
- if using OpenSSL 3+ one of: `xxd` (on Ubuntu/Debian is included with `vim`)
60+
or `printf` command (with %b directive) or `perl`
6161

6262
...and optionally:
6363

transcrypt

+24-4
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,26 @@ is_salt_prefix_workaround_required() {
188188
# (keyed with a combination of the filename and transcrypt password), and
189189
# then use the last 16 bytes of that HMAC for the file's unique salt.
190190

191+
# shellcheck disable=SC2155
192+
readonly IS_PRINTF_BIN_SUPPORTED=$([[ "$(echo -n "41" | sed "s/../\\\\x&/g" | xargs -0 printf "%b")" == "A" ]] && echo 'true' || echo 'false')
193+
194+
# Apply one of three methods to convert a hex string to binary data, or
195+
hex_to_bin() {
196+
# alternative 1 but xxd often only comes with a vim install
197+
if command -v "xxd" >/dev/null; then
198+
xxd -r -p
199+
# alternative 2, but requires printf that supports "%b"
200+
# (macOS /usr/bin/printf doesn't)
201+
elif $IS_PRINTF_BIN_SUPPORTED; then
202+
sed "s/../\\\\x&/g" | xargs -0 printf "%b"
203+
# alternative 3 as perl is fairly common
204+
elif command -v "perl" >/dev/null; then
205+
perl -pe "s/([0-9A-Fa-f]{2})/chr(hex(\$1))/eg"
206+
else
207+
die 'required command not found: xxd, or printf that supports "%%b", or perl'
208+
fi
209+
}
210+
191211
git_clean() {
192212
context=$(extract_context_name_from_name_value_arg "$1")
193213
[[ "$context" ]] && shift
@@ -216,7 +236,7 @@ git_clean() {
216236
if [ "$(is_salt_prefix_workaround_required)" == "true" ]; then
217237
# Encrypt the file to base64, ensuring it includes the prefix 'Salted__' with the salt. #133
218238
(
219-
echo -n "Salted__" && echo -n "$salt" | xxd -r -p &&
239+
echo -n "Salted__" && echo -n "$salt" | hex_to_bin &&
220240
# Encrypt file to binary ciphertext
221241
ENC_PASS=$password "$openssl_path" enc -e "-${cipher}" -md MD5 -pass env:ENC_PASS -S "$salt" -in "$tempfile"
222242
) |
@@ -396,10 +416,10 @@ run_safety_checks() {
396416
for cmd in {column,grep,mktemp,"${openssl_path}",sed,tee}; do
397417
command -v "$cmd" >/dev/null || die 'required command "%s" was not found' "$cmd"
398418
done
399-
# check for extra `xxd` dependency when running against OpenSSL version 3+
419+
420+
# check for a working method to convert a hex string to binary data
400421
if [ "$(is_salt_prefix_workaround_required)" == "true" ]; then
401-
cmd="xxd"
402-
command -v "$cmd" >/dev/null || die 'required command "%s" was not found' "$cmd"
422+
echo -n "41" | hex_to_bin >/dev/null
403423
fi
404424

405425
# ensure the repository is clean (if it has a HEAD revision) so we can force

0 commit comments

Comments
 (0)