Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 65 additions & 22 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,30 @@ USAGE
# setup.sh makes; there is no release at either, so this refuses them by
# name. A control character is refused before anything is echoed, and
# before it a character a terminal draws as something other than itself
# (#837), named by its code point: first, because `[![:print:]]` is the
# locale's, matching every byte past ASCII under `C` and none of those
# characters under a UTF-8 locale, where the refusal below would echo them.
# (#837), named by its code point: first, because the control check
# matches none of those characters, in any locale, and the owner/name
# refusal after it echoes the value.
#
# A CONTROL CHARACTER IS THE LAUNCHER'S RULE, #760's, which `main` holds
# the directory to (#940): under `LC_ALL=C`, in a subshell, `[[:cntrl:]]`
# or U+0080 to U+009F's two bytes (`\302`, then `\200` to `\237`), so the
# answer is the same in every locale. It was `[![:print:]]`, which under
# `C` matches every byte past ASCII: a letter past ASCII was refused as a
# control character there, and as no owner/name under a UTF-8 locale. It is
# no owner/name in either now, in those words. The trade is the launcher's
# (#867): a byte that is not UTF-8, as a lone `0x9B` or an overlong form of
# a control, passes, in every locale, and the refusal that names the value
# prints it: a terminal that reads UTF-8 draws it as a character it cannot
# read, and only one set to an 8-bit charset acts on it. `checked_version`
# and the option check in `main` hold their values to the same rule.
checked_repo() {
local misdrawn
misdrawn="$(LC_ALL=C; misdrawn_characters "$REPO")"
[ -z "$misdrawn" ] ||
die "\$OPENREPOSHAPE_REPO holds a character a terminal draws as something other than itself ($misdrawn): one that is invisible, is drawn as another character, ends a line or reorders the text around it. It must be an owner/name on github.com, such as opensoft/openRepoShape."
case "$REPO" in
*[![:print:]]*) die "\$OPENREPOSHAPE_REPO carries a control character; it must be an owner/name on github.com, such as opensoft/openRepoShape." ;;
esac
if (LC_ALL=C; case "$REPO" in *[[:cntrl:]]* | *$'\302'[$'\200'-$'\237']*) exit 0 ;; *) exit 1 ;; esac); then
die "\$OPENREPOSHAPE_REPO carries a control character; it must be an owner/name on github.com, such as opensoft/openRepoShape."
fi
case "$REPO" in
[A-Za-z0-9]*/[A-Za-z0-9._-]*) ;;
*) die "\$OPENREPOSHAPE_REPO is '$REPO', which is not an owner/name on github.com, such as opensoft/openRepoShape: this installer builds github.com URLs from it." ;;
Expand All @@ -151,7 +164,12 @@ checked_repo() {
# shape, which is the only one that echoes it), plus the empty value, and,
# between the length and the control character, a character a terminal
# draws as something other than itself, as the launcher's `ref_fault` has
# it (#837). Not shared, because this file arrives alone down a pipe.
# it (#837). The control character is `checked_repo`'s rule, above, with
# its trade (#940): a byte that is not UTF-8, as a lone `0x9B` or an
# overlong form of a control, passes, and a version with a letter past
# ASCII is the shape's to refuse, in its words, in every locale. A tag the
# redirect names is printable ASCII by then (`latest_from_redirect`). Not
# shared, because this file arrives alone down a pipe.
#
# THE SHAPE IS GIT'S RULE PART BY PART (#874), as `ref_fault`'s and
# `setup.sh`'s are: no `..`, no empty part between slashes, no part that
Expand All @@ -169,9 +187,9 @@ checked_version() {
misdrawn="$(LC_ALL=C; misdrawn_characters "$ref")"
[ -z "$misdrawn" ] ||
die "$what holds a character a terminal draws as something other than itself ($misdrawn): one that is invisible, is drawn as another character, ends a line or reorders the text around it. No release tag, branch or commit holds one."
case "$ref" in
*[![:print:]]*) die "$what carries a control character, which is not a release tag, branch or commit." ;;
esac
if (LC_ALL=C; case "$ref" in *[[:cntrl:]]* | *$'\302'[$'\200'-$'\237']*) exit 0 ;; *) exit 1 ;; esac); then
die "$what carries a control character, which is not a release tag, branch or commit."
fi
case "$ref" in
[!A-Za-z0-9]* | *..* | */.* | *.lock | *.lock/* | *//* | */ | *. | *[!A-Za-z0-9._/-]*) die "$what is '$ref', which is not a release tag, branch or commit: a ref starts with an ASCII letter or digit, uses only ASCII letters, digits, '.', '_', '/', '-', has no '..' (git reads it as a revision range), no empty part between slashes ('//', or a '/' at the end), no part that starts with '.' or ends in '.lock' (the name git gives the lock file it writes beside a ref), and does not end in '.'." ;;
esac
Expand All @@ -189,7 +207,7 @@ checked_version() {
# itself, never gathered into an array, so a reader and the analyser both
# see them there. `tests/test_install_sh.py` holds every curl line to it.
latest_from_redirect() {
local url="$1" headers line value status=0
local url="$1" headers line value tag status=0
FOUND=""
command -v curl >/dev/null 2>&1 || {
FAULT="curl is not installed"
Expand All @@ -213,13 +231,33 @@ latest_from_redirect() {
done
case "$value" in
*/releases/tag/?*)
FOUND="${value##*/releases/tag/}"
return 0
# The tag is the network's too, and `checked_version`, which
# it meets next, holds it to the byte rule a person's own
# values are held to (#940), whose trade passes a byte that
# is not UTF-8 and whose shape refusal prints the tag. So it
# is taken only when it is printable ASCII, under `LC_ALL=C`,
# which gives one answer in every locale. A release tag is
# ASCII, so this refuses no real one; any other tag names no
# release, unnamed, and `gh` is asked next.
tag="${value##*/releases/tag/}"
if (LC_ALL=C; case "$tag" in *[![:print:]]*) exit 1 ;; *) exit 0 ;; esac); then
FOUND="$tag"
return 0
fi
FAULT="it redirects to a location that names no release"
return 1
;;
esac
# The location is named only when it is text a terminal draws as
# it is: no control character, and no character it draws as
# something other than itself (#837).
# something other than itself (#837). It keeps the locale's
# `[![:print:]]`, not the byte rule a person's own values are
# held to (#940): it is the network's, naming it only lets the
# fault say more, and that class takes a byte that is not UTF-8,
# as a lone `0x9B` or an overlong form of a control, in no
# locale, where the byte rule's trade would print one from the
# network. The cost: under `C` a location with a letter past
# ASCII goes unnamed.
FAULT="it redirects to a location that names no release"
if [ -z "$(LC_ALL=C; misdrawn_characters "$value")" ]; then
case "$value" in
Expand Down Expand Up @@ -450,9 +488,12 @@ main() {
misdrawn="$(LC_ALL=C; misdrawn_characters "$1")"
[ -z "$misdrawn" ] ||
die "an option holds a character a terminal draws as something other than itself ($misdrawn): one that is invisible, is drawn as another character, ends a line or reorders the text around it. The one argument is a version, such as v1.0.1; with none, the newest release."
case "$1" in
*[![:print:]]*) die "an option carries a control character. The one argument is a version, such as v1.0.1; with none, the newest release." ;;
esac
# `checked_repo`'s rule for a control character, with its
# trade: a byte that is not UTF-8, as a lone `0x9B` or an
# overlong form of a control, passes (#940).
if (LC_ALL=C; case "$1" in *[[:cntrl:]]* | *$'\302'[$'\200'-$'\237']*) exit 0 ;; *) exit 1 ;; esac); then
die "an option carries a control character. The one argument is a version, such as v1.0.1; with none, the newest release."
fi
die "unknown option '$1'. The one argument is a version, such as v1.0.1; with none, the newest release."
;;
*)
Expand All @@ -474,11 +515,13 @@ main() {
# from the release that added the check, and only after this file had
# fetched it. The `case` is `install_commands`'s in `openRepoShape`,
# copied for the reason the drive-letter one below is, and the refusal
# says nothing of the value. `[[:cntrl:]]` and not `[![:print:]]`, which
# `checked_repo` uses: a directory with a letter the locale does not
# print (`café` under LC_ALL=C) is no fault of the directory's. The check
# runs under `LC_ALL=C` and names U+0080 to U+009F's two bytes (`\302`,
# then `\200` to `\237`), so a C1 control is refused in every locale,
# says nothing of the value. `[[:cntrl:]]` and not `[![:print:]]`: a
# directory with a letter the locale does not print (`café` under
# LC_ALL=C) is no fault of the directory's, and `checked_repo`,
# `checked_version` and the option check hold their values to these
# same bytes (#940). The check runs under `LC_ALL=C` and names U+0080
# to U+009F's two bytes (`\302`, then `\200` to `\237`), so a C1
# control is refused in every locale,
# whatever else the value holds, unless the locale reads those bytes as
# text (#858, below); U+2028 and U+2029, which only a UTF-8 locale's
# `[[:cntrl:]]` matched, are the next check's (#837).
Expand Down
58 changes: 41 additions & 17 deletions openRepoShape
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,12 @@ install_commands() {
# spelling below is. The control characters go first, and their refusal
# says nothing of the value, so that no refusal after it echoes one that
# can forge a line of output. It is `[[:cntrl:]]` and not
# `[![:print:]]`, which is what this file holds the repository and the
# ref to: a name with a letter the locale does not print, as `café`
# under LC_ALL=C, is no fault of the directory's. The check runs under
# `LC_ALL=C` and names U+0080 to U+009F's two bytes (`\302`, then `\200`
# to `\237`), so a C1 control is refused in every locale, whatever else
# `[![:print:]]`: a name with a letter the locale does not print, as
# `café` under LC_ALL=C, is no fault of the directory's, and the
# repository and the ref are held to these same bytes (#940,
# `checked_repo` below). The check runs under `LC_ALL=C` and names
# U+0080 to U+009F's two bytes (`\302`, then `\200` to `\237`), so a
# C1 control is refused in every locale, whatever else
# the value holds, unless the locale reads those bytes as text (#858,
# below); U+2028 and U+2029, which only a UTF-8 locale's `[[:cntrl:]]`
# matched, are the next check's (#837). Left to the locale,
Expand Down Expand Up @@ -794,11 +795,27 @@ find_python() {
# sent by the fetch with it. An owner/name keeps it inside the URL, before
# `.git`, so only those three forms lost it.
#
# A CONTROL CHARACTER IS #760's, AS `install_commands` READS ONE IN THE
# DIRECTORY (#940): under `LC_ALL=C`, in a subshell, `[[:cntrl:]]` or
# U+0080 to U+009F's two bytes (`\302`, then `\200` to `\237`), so the
# answer is the same in every locale. It was `[![:print:]]`, which is the
# locale's: under `C` and POSIX it matches every byte past ASCII, so a URL
# or a path with a letter past ASCII (`/srv/café/openRepoShape.git`) was
# refused there as carrying a control character, which it does not carry,
# where a UTF-8 locale and the package's `--version` took it. The trade is
# the directory's (#867): a byte that is not UTF-8, as a lone `0x9B` or an
# overlong form of a control, passes, in every locale, as it passes the
# package's check, and `--version` prints it: a terminal that reads UTF-8
# draws it as a character it cannot read, and only one set to an 8-bit
# charset acts on it. `setup.sh`, which is handed the clone URL as
# `$OPENREPOSHAPE_REPO`, holds it to the same rule, and refuses U+2028 and
# U+2029 there too, which this file refuses first by their code points
# (below).
#
# A CHARACTER A TERMINAL DRAWS AS SOMETHING OTHER THAN ITSELF IS REFUSED
# FIRST (#837), in words that name it by its code point and nothing else of
# the value. First, because `[![:print:]]` is the locale's: under `C` it
# matches every byte past ASCII, and under a UTF-8 locale none of these
# characters, so after it the words would change with the locale.
# the value. The control check after it matches none of these characters,
# in any locale, so this is the check that refuses them.
#
# install.sh's `checked_repo` is stricter, an owner/name and nothing else,
# because it builds only github.com URLs from the value.
Expand All @@ -808,9 +825,9 @@ checked_repo() {
misdrawn="$(LC_ALL=C; misdrawn_characters "$REPO")"
[ -z "$misdrawn" ] ||
die "OPENREPOSHAPE_REPO holds a character a terminal draws as something other than itself ($misdrawn): one that is invisible, is drawn as another character, ends a line or reorders the text around it. This tool will not put it on a \`git clone\` command line. Set it to a URL or a path."
case "$url$REPO" in
-* | *[![:print:]]*) die "OPENREPOSHAPE_REPO is not a value this tool will put on a \`git clone\` command line: it starts with '-' or carries a control character. Set it to a URL or a path." ;;
esac
if (LC_ALL=C; case "$url$REPO" in -* | *[[:cntrl:]]* | *$'\302'[$'\200'-$'\237']*) exit 0 ;; *) exit 1 ;; esac); then
die "OPENREPOSHAPE_REPO is not a value this tool will put on a \`git clone\` command line: it starts with '-' or carries a control character. Set it to a URL or a path."
fi
}

# A CHECKOUT OF THE STANDARD, made the way `setup.sh` self-bootstraps one:
Expand Down Expand Up @@ -874,9 +891,9 @@ shape_checkout() {
# A CHARACTER A TERMINAL DRAWS AS SOMETHING OTHER THAN ITSELF (#837) is a
# fault between the length and the control character, named by its code
# point and never echoed, as `checked_repo` refuses one: before the
# control check, whose `[![:print:]]` is the locale's, so the words do not
# change with the locale, and before the shape, which echoes the value.
# Those two are `ref_character_fault`'s, below.
# control check, which matches none of these characters in any locale
# (#940), and before the shape, which echoes the value. Those two are
# `ref_character_fault`'s, below.
#
# THE SHAPE IS GIT'S RULE PART BY PART (#874), as `setup.sh`'s and
# `install.sh`'s are: no `..`, no empty part between slashes, no part that
Expand Down Expand Up @@ -913,16 +930,23 @@ ref_fault() {
# as it reads, and an install that does not record the ref takes one that
# names no ref at all (workBenches', `record_ref`), so those two are left to
# where a ref is used.
#
# THE CONTROL CHARACTER IS `checked_repo`'s RULE, #760's bytes under
# `LC_ALL=C`, with its trade (#940): a byte that is not UTF-8, as a lone
# `0x9B` or an overlong form of a control, passes. A ref with a letter past
# ASCII (`café`) carries no control character in any locale, and is the
# shape's to refuse where the ref is used, in the shape's words, as a UTF-8
# locale had it.
ref_character_fault() {
local ref="$1" what="$2" misdrawn
misdrawn="$(LC_ALL=C; misdrawn_characters "$ref")"
if [ -n "$misdrawn" ]; then
printf '%s' "$what holds a character a terminal draws as something other than itself ($misdrawn): one that is invisible, is drawn as another character, ends a line or reorders the text around it. No branch, tag or commit this tool will pass to \`git checkout\` holds one."
return 0
fi
case "$ref" in
*[![:print:]]*) printf '%s' "$what carries a control character, which is not a branch, tag or commit this tool will pass to \`git checkout\`." ;;
esac
if (LC_ALL=C; case "$ref" in *[[:cntrl:]]* | *$'\302'[$'\200'-$'\237']*) exit 0 ;; *) exit 1 ;; esac); then
printf '%s' "$what carries a control character, which is not a branch, tag or commit this tool will pass to \`git checkout\`."
fi
}

checked_ref() {
Expand Down
Loading
Loading