节点:评论gawk:cmd。行:70:(FILENAME = .. / doc / m4.texinfo FNR = 919)致命:\ {\}的无效内容:/ @ tabchar {} /

时间:2019-05-08 05:43:16

标签: awk

我在修补开源软件易受攻击的问题时遇到了问题,这是在m4开源中发现的CVE-2008-1687。

问题日志是

  

cd [build_DIR] /m4/1.4.9-r2/m4-1.4.9/checks && AWK = gawk ./get-them ../ doc / m4.texinfo

     

(....跳过)

     

节点:评论gawk:cmd。行:70:(FILENAME = .. / doc / m4.texinfo FNR = 919)致命:Invalid content of \{\}: /@tabchar{}/

该日志说执行gawk命令直到m4.texinfo文件的第918行和Invalid content of \{\}: /@tabchar{}/错误在行919处发生。但是,找不到\{\}内容和/@tabchar{}/字符在m4.texinfo的919行。 因此,我想知道为什么会发生该错误以及如何解决该错误。

[获取]

/^@example$/, /^@end example$/ {
if (seq < 0)
    next;
if ($0 ~ /^@example$/) {
    if (count > 0)
        close (file);
    seq++;
    count++;
    file = sprintf("%03d.%s", count, node);
    printf("dnl @ %s:%d: Origin of test\n"\
        "dnl @ expected status: %d\n"\
        "dnl @ Copyright (C) 2006, 2007 Free Software Foundation\n"\
        "dnl @ This file is free software; the Free Software Foundation\n"\
        "dnl @ gives unlimited permission to copy and/or distribute it\n"\
        "dnl @ with or without modifications, as long as this notice\n"\
        "dnl @ is preserved.\n", FILENAME, NR, status) > file;
    status = 0;
    next;
}
if ($0 ~ /^@end example$/) {
    next;                                             // line 70
}
if ($0 ~ /^\^D$/)
    next;
if ($0 ~ '/^@result\{\}/' || $0 ~ '/^@error\{\}/')
    prefix = "dnl ";
else
    prefix = "";
gsub("@@", "@", $0);
gsub("@{", "{", $0);
gsub("@}", "}", $0);
gsub("@w{ }", " ", $0);
gsub("@tabchar{}", "\t", $0);
printf("%s%s\n", prefix, $0) >> file;

}

  

[m4.texinfo]

     

@node注释   @code {m4}输入中的@section注释

     

@cindex评论   @code {m4}中的注释通常由字符@samp {#}分隔。   和换行符。注释定界符之间的所有字符都将被忽略,   但整个注释(包括定界符)将传递给   输出---注释将被@code {m4}丢弃@emph {not}。

     

注释不能嵌套,因此@samp {#}之后的第一个换行符结束   评论。开始注释字符串的注释效果   可以通过引用禁止它。

     

@示例

     

quoted text' #注释文字'//第919行

     

@result {}引号#注释文本

     

quoting inhibits'#'`评论'

     

@result {}引用禁止#条注释

     

@end示例

1 个答案:

答案 0 :(得分:0)

您指示的行是第70行:

next;                                             // line 70

显然不是awk脚本的第70行,因为它不包含错误消息告诉您在第70行产生了失败的文本:

Invalid content of \{\}: /@tabchar{}/

在此代码的正则表达式中:

gsub("@tabchar{}", "\t", $0);

{}是一个RE间隔(如x{3}表示x的3个重复)-它不能为空,我怀疑您想要{}仍然被视为文字。

看:

$ echo 'foo@tabchar{}bar' | awk 'gsub("@tabchar{}", "\t", $0);'
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: Invalid content of \{\}: /@tabchar{}/

$ echo 'foo@tabchar{}bar' | awk 'gsub("@tabchar\{\}", "\t", $0);'
awk: cmd. line:1: warning: escape sequence `\{' treated as plain `{'
awk: cmd. line:1: warning: escape sequence `\}' treated as plain `}'
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: Invalid content of \{\}: /@tabchar{}/

$ echo 'foo@tabchar{}bar' | awk 'gsub("@tabchar\\{\\}", "\t", $0);'
foo     bar

您需要2个转义,因为您在正则表达式上下文中使用了一个字符串,因此awk必须先将字符串转换为正则表达式(使用一组转义符),然后将其用作正则表达式(使用其余的设置)在转义表达式周围使用regexp(/.../)而不是字符串("...")分隔符可以避免这种情况和其他问题:

$ echo 'foo@tabchar{}bar' | awk 'gsub(/@tabchar\{\}/, "\t", $0);'
foo     bar

您还应该考虑要对脚本其他部分中的正则表达式周围的单引号做些什么,例如:

if ($0 ~ '/^@result\{\}/' || $0 ~ '/^@error\{\}/')

我认为您可能打算写:

if ($0 ~ /^@result\{\}/ || $0 ~ /^@error\{\}/)

等同于:

if (/^@result\{\}/ || /^@error\{\}/)

甚至只是:

if (/^@(result|error)\{\}/)