acmesh-official / acme.sh

A pure Unix shell script implementing ACME client protocol
https://acme.sh
GNU General Public License v3.0
38.7k stars 4.91k forks source link

_egrep_o broken on docker images #2414

Open codestation opened 5 years ago

codestation commented 5 years ago

This bug was reported on #1364 and a pull request was made that solved the problem on #1366 but it was never merged and instead a workaround was pushed.

Right now on on the latest version (2.8.2) dns_linode.sh and dns_linode_v4.sh (and maybe others) are broken because this bug (the domain cannot be found) Can #1366 be properly merged? I made a test case to further demonstrate that the current implementation is broken because the pipe cannot be read twice.

Steps to reproduce

test.sh

#!/bin/sh

_egrep_o1() {
  egrep -o "$1" 2> /dev/null
}

_egrep_o2() {
  sed -n 's/.*\('"$1"'\).*/\1/p'
}

_egrep_o() {
  if ! egrep -o "$1" 2>/dev/null; then
    sed -n 's/.*\('"$1"'\).*/\1/p'
  fi
}

_egrep_o_fix() {
  stdin=$(cat)
  if ! echo "$stdin" | egrep -o "$1" 2>/dev/null; then
    echo "$stdin" | sed -n 's/.*\('"$1"'\).*/\1/p'
  fi
}

echo "egrep -o test:"
echo '{"pages": 1, "results": 2, "data": [
{"id": 1, "domain": "example.org"},
{"id": 2, "domain": "example.com"},
{"id": 3, "domain": "example.net"}], "page": 1}' | _egrep_o1  '{.*"domain":\s*"example.com".*}'

echo "sed -n test:"
echo '{"pages": 1, "results": 2, "data": [
{"id": 1, "domain": "example.org"},
{"id": 2, "domain": "example.com"},
{"id": 3, "domain": "example.net"}], "page": 1}' | _egrep_o2  '{.*"domain":\s*"example.com".*}'

echo "_egrep_o() test:"
echo '{"pages": 1, "results": 2, "data": [
{"id": 1, "domain": "example.org"},
{"id": 2, "domain": "example.com"},
{"id": 3, "domain": "example.net"}], "page": 1}' | _egrep_o  '{.*"domain":\s*"example.com".*}'

echo "_egrep_o_fix() test:"
echo '{"pages": 1, "results": 2, "data": [
{"id": 1, "domain": "example.org"},
{"id": 2, "domain": "example.com"},
{"id": 3, "domain": "example.net"}], "page": 1}' | _egrep_o_fix  '{.*"domain":\s*"example.com".*}'
$ docker run -it --rm -v $PWD/test.sh:/test.sh ubuntu:18.04 /test.sh
egrep -o test:
{"id": 2, "domain": "example.com"}
sed -n test:
{"id": 2, "domain": "example.com"}
_egrep_o() test:
{"id": 2, "domain": "example.com"}
_egrep_o_fix() test:
{"id": 2, "domain": "example.com"}
$ docker run -it --rm -v $PWD/test.sh:/test.sh alpine:3.10 /test.sh
egrep -o test:
sed -n test:
{"id": 2, "domain": "example.com"}
_egrep_o() test:
_egrep_o_fix() test:
{"id": 2, "domain": "example.com"}

The test also includes individual grep/sed calls to see that they aren't broken when used directly.

dkerr64 commented 5 years ago

Is this a dup of #2385?

codestation commented 5 years ago

@dkerr64 no, because in this case the regular expression isn't the culprit. The problem comes because on alpine (their grep doesn't support extended regex) _e_grep_o tries to use the pipe input twice and tries to run the regex on sed with an empty input.

Still, #2385 cannot even be fixed because the whole function is flawed until #1366 is merged.

dkerr64 commented 5 years ago

@codestation okay thank you. I have decided to stop using _e_grep_o() as I can use standard grep without extended regex. I have a PR #2434 awaiting @Neilpang to merge for FreeDNS for this. Thanks.