如何解决如何将用户输入清理为有效的 C-String 文字?
我正在尝试使用 shell 脚本生成用于包装可执行文件的 C 代码。
这需要在 Linux 和 MacOS 上运行,并且依赖项尽可能少。我不关心 Windows(WSL2 除外)
#include <unistd.h>
#include <stdlib.h>
int main(int argc,char **argv) {
putenv("X=1");
putenv("HELLO=WORLD")
argv[0] = "/usr/bin/python3";
return execv("/usr/bin/python3",argv);
}
幼稚的方法:
# make-c-wrapper.sh EXECUTABLE ARGS
#
# ARGS:
# --argv0 NAME : set name of executed process to NAME
# (defaults to EXECUTABLE)
# --set VAR VAL : add VAR with value VAL to the executable’s
# environment
echo "#include <unistd.h>\n#include <stdlib.h>\n\nint main(int argc,char **argv) {"
executable="$1"
params=("$@")
for ((n = 1; n < ${#params[*]}; n += 1)); do
p="${params[$n]}"
if [[ "$p" == "--set" ]]; then
key="${params[$((n + 1))]}"
value="${params[$((n + 2))]}"
n=$((n + 2))
echo " putenv(\"$key=$value\");"
elif [[ "$p" == "--argv0" ]]; then
argv0="${params[$((n + 1))]}"
n=$((n + 1))
else
# Using an error macro,we will make sure the compiler gives an understandable error message
echo " #error make-c-wrapper.sh did not understand argument $p"
fi
done
echo " argv[0] = \"${argv0:-$executable}\";\n return execv(\"$executable\",argv);\n}"
但是如果您尝试在输入中提供特殊字符,则会失败:
./make-c-wrapper /usr/bin/python3 --set "Hello" "This is\"\na test"
#include <unistd.h>
#include <stdlib.h>
int main(int argc,char **argv) {
putenv("Hello=This is"
a test");
argv[0] = "/usr/bin/python3";
return execv("/usr/bin/python3",argv);
}
我希望在这里看到的是:
#include <unistd.h>
#include <stdlib.h>
int main(int argc,char **argv) {
putenv("Hello=This is\"\na test");
argv[0] = "/usr/bin/python3";
return execv("/usr/bin/python3",argv);
}
根据此答案:https://stackoverflow.com/a/12208808/8008396,似乎我需要转义以下字符以确保结果是有效的 C 字符串文字:"
、\
、{{ 1}}、\r
、\n
和 \0
。
有没有简单的方法可以做到这一点?它需要在 MacOS 上运行,而不仅仅是在 Linux 上运行。
解决方法
似乎我需要转义以下字符以确保结果是有效的 C 字符串文字:"
、\
、\r
、\n
、{ {1}} 和 \0
。
您需要转义 \?
、"
和换行符。当你这样做时,逃避回车是有意义的。尽管 \
有一个转义序列,但该字符也可以表示它自己。输入中的空字符不能表示为字符串文字的元素,而且您的 shell 可能也不在变量值中处理它们,因此您最好不要对它们给予任何特殊考虑。
Shell 参数扩展语法具有子字符串替换功能和您可以利用的类似 C 的文字语法。 shell 引用有点复杂,但例如,这个 ...
?
...打印
escape_string_literal() {
result=${1//'\'/'\\'}
result=${result//\"/'\"'}
result=${result//$'\n'/'\n'}
result=${result//$'\r'/'\r'}
}
escape_string_literal '"boo\"'
echo "${result}"
但是请注意,您不一定清楚在字符串文字中包含所有其他字符。特别是,即使其中大多数没有单字符转义,其他控制字符也可能会或可能不会被接受为文字字符,这取决于您的 C 实现。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。