Jac*_*ary 4 c string system quoting
system()
我的代码里面有一个使用awk 的命令.我无法弄清楚如何解决\x00
十六进制值的问题.显然他们需要以不同的方式被终止,但这超出了我所知道的范围.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char command[128];
snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
system(command);
}
Run Code Online (Sandbox Code Playgroud)
警告/错误:
> test.c:8:56: warning: format string contains '\0' within the string body [-Wformat]
> snprintf(command, sizeof(command), "awk '{ gsub (/\xAB\x00\xBC/,\"\xBC\x00\x00\xAB\") ; print }' %s", argv[1]);
> /usr/include/secure/_stdio.h:57:62: note: expanded from macro 'snprintf'
> __builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
^
1 warning generated.
sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
对不起,如果之前有人询问,我在搜索中找不到任何相关信息,如何解决这个问题,谢谢......
考虑C字符串文字"\xAB"
.此字符串文字包含一个字节,而不是4.同样,"\x00"
是一个字符串文字,其中包含一个空字节的字节.Clang警告你,因为空字节结束了C字符串 - 其后的每个字符都会被库函数忽略,例如snprintf
.
在你的awk代码中,有一个awk字符串文字,用双引号括起来.你…\"\xBC\x00\x00\xAB\"…
在双引号前写了反斜杠,因为否则双引号会被解释为结束C字符串文字.同样,如果你想在awk代码中更准确地使用反斜杠(更确切地说,在shell命令中),你需要在它前面加上另一个反斜杠.换句话说,你需要加倍你的反斜杠.
snprintf(command, sizeof(command), "awk '{ gsub (/\\xAB\\x00\\x00\\xBC/,\"\\xBC\\x00\\x00\\xAB\") ; print }' %s", argv[1]);
Run Code Online (Sandbox Code Playgroud)
请注意您的程序还有另一个引用问题:它将其参数解释为shell代码片段,而不是文件名.如果文件名不包含任何shell特殊字符,则两者仅重合.例如,./your_program Jack.txt
将工作,但不是./your_program "O'Leary.txt"
.要使其工作,您需要按下参数以保护shell特殊字符.
(另一个问题是你不检查是否snprintf
成功.它可能会溢出 - 你应该根据参数的长度动态分配必要的大小(如果参数包含特殊字符,不要忘记考虑额外的引用). )