thaliaarchi
Joined 6 years ago
Joined 6 years ago
The engine chosen by MicroPython is vulnerable to catastrophic backtracking and switching to the Pike VM implementation would fix that. Instead of backtracking in the text when the pattern doesn't match, the Pike VM iterates each char in the text only once, visiting the states valid for that position in lock step. Consequently, it allocates a list of “thread”s, proportional in length to the number of states in the pattern (though usually patterns have relatively few states). Many security issues have resulted from regexp denials of service, so this slight memory tradeoff might be worthwhile.
Since recursiveloop.c has been changed by MicroPython, those changes would need to be ported to pike.c. The fixes are small and none of the extra features exploit the backtracking, so this should be easy.
[0]: https://github.com/micropython/micropython/tree/master/lib/r...
> Excel 2.0 was released a month before Windows 2.0, and the installed base of Windows was so low at that point in 1987 that Microsoft had to bundle a runtime version of Windows 1.0 with Excel 2.0.
> I made a prototype and, lo and behold, it was in fact slow, as predicted. (I’m smart.)
And in another article[0], describing an inefficient collision algorithm:
> Mojang’s decision never crossed my mind. I guess I’m not a real programmer.
[0]: https://purplesyringa.moe/blog/ru/minecraft-compares-arrays-...
#!/usr/bin/env bash
set -eEuo pipefail
# `git commit`, using the latest file modification time as the commit and author
# dates, when GIT_AUTHOR_DATE or GIT_COMMITTER_DATE, respectively, is not set.
# Use fractional seconds when available to display the newest file more
# accurately, even though Git only uses seconds.
if which gstat >/dev/null; then
stat=(gstat --format='%.Y %n') # Detected aliased GNU coreutils
elif stat --version 2>/dev/null | grep -q 'GNU coreutils'; then
stat=(stat --format='%.Y %n') # Detected GNU coreutils
else
stat=(stat -f '%m %N') # Fallback to BSD-style, which only reports seconds
fi
# Select the latest modified time of all staged files, excluding deletions.
modified="$(
cd "$(git rev-parse --show-toplevel)" &&
git diff --staged --diff-filter=d --name-only -z |
xargs -0 "${stat[@]}" |
sort -rn |
head -1
)"
modified_seconds=
if [[ -n $modified ]]; then
modified_seconds="${modified%% *}"
modified_file="${modified#* }"
modified_date="$(date -r "${modified_seconds%.*}" +'%Y-%m-%d %H:%M:%S %z')"
echo "Modify date: $modified_date ($modified_file)"
fi
author_seconds="$modified_seconds"
committer_seconds="$modified_seconds"
if [[ -n ${GIT_AUTHOR_DATE+.} ]]; then
echo "Author date: ${GIT_AUTHOR_DATE:-now}"
fi
if [[ -n ${GIT_COMMITTER_DATE+.} ]]; then
echo "Commit date: ${GIT_COMMITTER_DATE:-now}"
else
last_commit_seconds="$(git show -s --format=%at HEAD 2>/dev/null || echo 0)"
if [[ $modified_seconds < $last_commit_seconds ]]; then
committer_seconds=
echo "Commit date: now (last commit: $(git show -s --format=%ai HEAD 2>/dev/null))"
fi
fi
GIT_AUTHOR_DATE="${GIT_AUTHOR_DATE-"$author_seconds"}" \
GIT_COMMITTER_DATE="${GIT_COMMITTER_DATE-"$committer_seconds"}" \
exec git commit "$@"