Delphi 2006中EOLN存在bug

7

我认为在D2006(WIN 32)的EOLN函数中存在一个bug,当应用于具有Unix类型换行符(LF)的文本文件时,如果这个LF是输入缓冲区中的第一个字符,则会出现问题。这个bug的源代码是这一行:

        TEST    [EDX].TTextRec.Mode,tfCRLF

应该正确阅读为:
        TEST    [EDX].TTextRec.Flags,tfCRLF

存储换行样式的是Flags字段,而不是存储输入/输出模式的Mode字段。

上面这行是从System单元中的以下代码片段中提取出来的,当需要重新填充缓冲区时会调用该代码。由于对于输入文件(通常与EOLN一起使用的模式)Mode字段是奇数,因此该错误未被注意到。

fmInput  = $D7B1;

在Windows生成的文本文件中,tfCRLF(=1)匹配唯一设置的位。新版本的Delphi是否仍具有相同的EOLN编码?

function _Eoln(var t: TTextRec): Boolean;
asm
.
.
.
@@readChar:
        PUSH    EAX
        CALL    _ReadChar
        POP     EDX
        CMP     AH,cEOF
        JE      @@eof
        DEC     [EDX].TTextRec.BufPos
        XOR     ECX,ECX
        XCHG    ECX,EAX
        TEST    [EDX].TTextRec.Mode,tfCRLF
        JE      @@testLF
        CMP     CL,cCR
        JE      @@eol
        JMP     @@exit

@@eol:
@@eof:
        MOV     AL,1
@@exit:
end;

还有一个奇怪的地方:当应用于Windows (CRLF)文件类型时,这个EOLN函数实际上只检查CR,就好像它是一个(旧的?)Mac文件,不会检查后面是否有LF!?


1
@Jeroen:没错。我不想让Marcelo误以为报告问题会在某个时候修复D2006。 :-) - Ken White
@KenWhite 已经注意到了。在未来建议对旧产品报告错误时,会解释清楚这一点。 - Jeroen Wiert Pluimers
@Jeroen和KenWhite:但是那些更新版本的Delphi中的错误怎么办?你们能否看一下System.Eoln并告诉我它是否仍然存在?如果是,我肯定会向EMBT报告。 - Marcelo Bergweiler
1
@MarceloBergweiler 如果您提供一个可重现的测试用例(最好是基于DUnit的,因为这个测试框架已经随Delphi一起发布了很长时间),我可以进行检查。 - Jeroen Wiert Pluimers
1
@Jeroen:因为我们无法在这里附加文件,所以我准备了一个ZIP文件,并将其附加到新的EMBT报告#124205 - Marcelo Bergweiler
显示剩余3条评论
1个回答

0

这在2007年没有被修复

以下是Delphi 2007的代码

function _Eoln(var t: TTextRec): Boolean;
asm
  ....
  TEST    [EDX].TTextRec.Mode,tfCRLF <<-- incorrect reference still there
  JE      @@testLF
  CMP     CL,cCR
  JE      @@eol
  JMP     @@exit
@@eol:
@@eof:
      MOV     AL,1
@@exit:
end;

在XE6中修复
Delphi XE6使用了纯Pascal版本,它也正确地检查t.Flags。
(显然否则它将无法编译)。

我没有检查过之间是否有任何退化。


Johan,D2007的代码与D2006完全相同。错误在您的代码下部,在以“@@readChar”开头的部分中。您会发现那里对“Mode”的引用是错误的。 - Marcelo Bergweiler
糟糕,不过在XE6中已经修复了。 - Johan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接