我发现的Delphi 6的Bug列表,请各位参考~~~~~~~~(200分)

  • 主题发起人 主题发起人 aimingoo
  • 开始时间 开始时间
A

aimingoo

Unregistered / Unconfirmed
GUEST, unregistred user!
用D6可能是最早的一批,将D6 Uninstall可能也是最早的一批。下面是短短两三天发现的Bug
列表,没时间测试更多的错误了。就下面这些,已经足够我放弃Delphi 6了。:(
记得论坛里有在borland上班的朋友,如果可以,请提交一个Bug报告给borland吧。我没时间
写成E文了。:(
发现这些错误已经是近两个月前的事了,大富翁一直不好上,就等到现在才发,算是给所有大
小富翁的一份小礼吧。Aiming最近忙,不一定会来看看这个贴,有更多的问题大家尽管提好了。
哈哈。更多的Bugs列表,请大家附后。——不过,最好要证实过的。^-^
-----------------------------------------------
Delphi 6 Bugs. Find and Fixed By Aiming.
-----------------------------------------------
1. Delphi5/6中一个不兼容的String操作
-----------------------------------------------
const aNameStr='Guest';
type aNameType=string[length(aNameStr)];
var s:string;
procedure TForm1.Button1Click(Sender: TObject);
begin
s:='Guest5';
if aNameType(s)=aNameStr then
showMessage('ture');
end;

分析:
Delphi5中,正常识别aNameType(s)为'Guest',而Delphi6中
识别为'Guest'#0,从而导致不兼容。
2. Delphi6中无法重设线程优先级
-----------------------------------------------
constructor TsysChk.Create();
begin
{$ifndef VER140}
//Delphi6中在ISAPI线程中控制优先级会导致一个IIS的异常!!!
Priority := tpHigher;
{$endif}
inherited Create(False);
end;

3. Delphi4/5/6中均无法有效地对URL中的Unicode进行解码
-----------------------------------------------
function HTTPDecode(const AStr: String): String;
var
//...
pWideChar : array[0..1] of WORD;
pCChar : string[2];
//...
begin
//...
{//next fix by Aiming. old source:
S := '$' + Cp^ + Sp^;
Rp^ := Chr(StrToInt(S));
}
if Cp^<>'u'
then
begin
S := '$' + Cp^ + Sp^;
Rp^ := Chr(StrToInt(S));
end
else
//is UNICODE!!!
begin
Cp := Sp;
inc(Sp);
//skip char 'u'
if Sp^=#0
then
raise EWebBrokerException.CreateFmt(sErrorDecodingURLText, [Cp - PChar(AStr)])
else
begin
S := '$' + Cp^ + Sp^;
inc(Sp);
Cp := Sp;
inc(Sp);
S := S + '$' + Cp^ + Sp^;
pWideChar[0] := StrToInt(S);
pCChar := WideCharToString(@pWideChar);
Rp^ :=pCChar[1];
inc(Rp);
Rp^ :=pCChar[2];
end;
end
//...
end
分析:
Delphi4及以上版本的Web编程中,引用到httpapp.pas文件。该文件中的function HTTPDecode()存在上述错误。导致这个
错误码的原因是因为在IE中的JavaScript中的Escape()函数对双字节字串直接编码成Unicode模式的字串,即"%uxxxx"!而在
Netscape/Opera等浏览器中都按"%xx%xx"来进行编码的。因为前者是个在W3C中没有声明过的处理方法!
上面修正过的处理方法能够正常地处理通过IE的Escape()函数编码过的URL/Content. :)
4. Delphi6中对INIFile的重名项的取值方法与Delphi3/4/5存在不同
-------------------------------------------------------------------
这个错误将导致一些对IniFile的取值出现与低版本不兼容的情况。如下:
[testSection]
TableName=SectionList
Condition=ConditionValue_1
Condition=ConditionValue_2
Condition=ConditionValue_3
对上述Ini节test_Section取值时,ReadString('testSection','Condition','')取到的值在Delphi5中是ConditionValue_1,而在Delphi6中是ConditionValue_3。即Delphi6在重名的项取值是取最未项,而Delphi5是取最首项。这意味着一些试图利用重名项来传多个参数或者屏蔽项目的操作在D5/D6中存在不同。
分析:
Delphi5中对INIFile的操作是使用标准的winAPI来进行的,在ReadString()中,调用GetPrivateProfileString() API来读取值。
而在Delphi6中,考虑到对大型INI File的处理的速度问题,Delphi6重写了一个THashedStringList类,用来存储INIFILE节中的Name,并用Hash方法来实现Name在StringList中的检索,这样可以大幅度提升TStringList.Value['aName']这个操作的速度。--而这个操作是TStrings的操作中最常用的。
在实现THashedStringList类时,--可能是出于检索速度的考虑,也可能是因为Hash方法本身的需要--Delphi6检索到Name时,得到的结果是最未的一个Hash结点。这样,IniFile的操作中,也就得到了最后一个"Name=Value"值对。
很明显,上述问题是一个Bug,因为Delphi重新实现的ReadString()与WinAPI中的GetPrivateProfileString()函数不兼容。而INIFile是Windows的一个配置文件标准,也就意味着应当使用Windows标准的接口。
5. Delphi x处理for循环初值与TurboPascal不相容
-------------------------------------------------------------------
如下代码:
-----------------------------------------------
var i,j : integer;
begin
j := -2;
for i := 0 to j do
begin
writeln('test');
end;
writeln(i);
readln;
end.
-----------------------------------------------
在TurboPascal上运行时,你会看到i被输出为0,而在Delphi中,输出为一个随机的整数。
在Pascal中,"for i:=0 to n do
;"这样的操作是先给i初值,然后在"end;
"时递增/减,这是Pascal标准的做法。然而Delphi实现时却没有这样做,(可能是出于效率的考虑)它在循环次数为0时,将不赋初值。:(
因此导致出错。:(
解决方案:
在for之前加赋初值的代码:
-----------------------------------------------
var i,j : integer;
begin
j := -2;
i := 0;
for i := 0 to j do
begin
writeln('test');
end;
writeln(i);
readln;
end.
---------------------------------------------
6. Delphi5中使用动态数组作为函数入口参数的一个Bug~~~
------------------------------------------------------------
本Bug我在D5(sp2)中发现,没有在D6上测试过(已经uninstall了),大家参考一下。
如下代码:
procedure delNodes(aBox:array of integer;
isGuest:boolean=false);
begin

if isGuest then
showMessage('true') else
showMessage('false');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

delNodes([]);
end;

测试上面的代码,我们会发现:当Button1按下时,delNodes调用结果是出现一个消息框,显示'true'!!!问题是,按照接口描述,如果isGuest参数缺省,则应该取值False,也就是说,应该显示成'false'。
分析:
-----------
这里的结果显然违反了Delphi5对函数缺省参数的定义。但是,原因可能出在Delphi5对函数入口参数的栈的处理有错误。因为无法修改到Delhi RTL级的处理代码,所以,上述问题无法解决。在这里,只能使用delNodes([],true)或者delNodes([],false)来显示地调用这个函数,或者不定义isGuest为缺省参数。
另外,我们不能试图将isGuest调整到aBox参数之前。因为Delphi要求“缺省参数”必须作为函数参数最后的一个/几个参数。
作为一个辅助的解决方案,我们可以用下面的代码来模拟上述的函数定义。——如果你必须要这样做的话。——你的确可以实现类似于缺省参数的效果,但仅是效果而已。
-----------------------------------------------------------------------------
procedure delNodes(aBox:array of integer;
isGuest:boolean);overload;
begin

if isGuest then
showMessage('true') else
showMessage('false');
end;

procedure delNodes(aBox:array of integer);
overload;
begin

delNodes(aBox, false);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

delNodes([]);
end;

-----------------------------------------------------------------------------
7. Delphi 6对断点的设定有错误,另外,常量定义存在重大的BUG!!!
-------------------------------------------------------------------
请参考如下出错图片:
http://202.102.247.230/soft/aDelphiError.jpg
图片中的实例只是一个极简单的项目,就只有那样的几行代码。
有如下问题:
1. 调试断点事实上是"end.
"行的断点,Delphi6居然还数不清楚源代码行???
2. 常量定义的用法没错吧?是的,没错!但结果呢?如果你在断点位置打Ctrl+F7,你会发现,ExtSQLLine_MutilPage常量的值如下:
------------------------------------------------------------------
DECLARE @V1 int, @V2 int, @V3 int, @V4 int, @V5 %S
SET @V1=%S;
SET @V2=%S;
SET @V4=@V1*@V2+1
SELECT @V3=count(%S) FROM %S %S
IF (@V4>@V3) SET @V5=NULL
else
begin
SET ROWCOUNT @V4;
SELECT @V5=%S FROM %S %S %S END
SELECT %S INTO %S FROM %S WHERE (%S%S@V5) %S %S
SELECT @V4=@@RowCount
SET ROWCOUNT 0
------------------------------------------------------------------
天啊!“SET ROWCOUNT @V2”这一行定义居然被Delphi吃掉了!!!!!!!!
一个常量中间的值,还会被吃掉???一个常量定义都会出错!!!Delphi,你是不是真的要灭亡了?????

=============================================
很多的时候,我信任Borland,但更多的时候,我宁可去读完它的源码,然后再来发表对
Borland的看法。我一面承认着那些程序员的优秀和代码的品质,一面抱怨着这样那样的
BUG。无论如何,BUG还是BUG,一如既往的多。作为在对这些在M$ Windows平台上唯一抗
衡的编译器开发人员,和在大富翁里里外外的这些Delphi Fans最高的尊敬,我除了只能
提出这些Bug,还能说什么呢?
接下来的事,可能还是只有低头,并按下alt + p + b键,继续我的工作了罢。:(~~~
 
谢谢! 我会转告 y9y. 他现在在 Borland 做 QA.
 
D6的确存在不少bug, 在IDE方面发现的更多。
不过可能是aimingoo使用时间不长,有些内容没有仔细看了,
比如:
5. Delphi x处理for循环初值与TurboPascal不相容
Delphi中的帮助是这样说明的:
If initialValue is greater than finalValue in a for...to statement, or less than
finalValue in a for...downto statement, then
statement is never executed.
After the for statement terminates, the value of counter is undefined.
在各个版本的Delphi中好象都是这样,而且Borland也好,高校的教师也好,
一般不建议在循环体后再对循环变量进行使用,因为不同的编译器对它的处理是不同的,
这一点在C中也十分突出。
6. Delphi5中使用动态数组作为函数入口参数的一个Bug~~~
在D6中没有这个问题
7. Delphi 6对断点的设定有错误,另外,常量定义存在重大的BUG!!!
奇怪,你也是按单步的吧,
我试着没有问题呀,
你能把操作过程再重复一遍吗?
我想这样borland也好更确切地找到问题所在。
 
噢,刚才又试了一下第一个问题
1. Delphi5/6中一个不兼容的String操作
const aNameStr='Guest';
type aNameType=string[length(aNameStr)];
var s:string;
procedure TForm1.Button1Click(Sender: TObject);
begin
s:='Guest5';
if aNameType(s)=aNameStr then
showMessage('ture');
end;

在我的机器上D6正确地执行了,
s被强制转换成'Guest'。
如果你的结果与我的相反,我在想你用的是测试版?还是别的什么原因?
 
不好意思,
我是对我熟悉的内容先看的,
我认为
4. Delphi6中对INIFile的重名项的取值方法与Delphi3/4/5存在不同
这的确是个问题,Borland在处理ini文件应保持与MS的一致性。
不过在ini文件中使用“重名的项”对于我来说是一件比较新鲜的用法。
其它部分我没有试了
 
AIMINGOO,你好
谢谢你提的那些BUG,我这就去仔细核对。我因为负责VCL方面的,所以核实之后,
我会向我负责这方面的同事汇报。
另外,在新版大富翁上,我已经不知道如何查找对方的EMAIL地址了,您能否把你
的EMAIL地址留给我: tianhai@hotmail.com
我想,你提出的一些方面不是我熟悉的,我可能会需要和你联络。谢谢。
 
AIMINGOO
BUG1:如AMO证实,无法重复你的结果
每次都是显示TRUE
版本是6.0.6.163/Window2000
 
AIMINGOO
抱歉,我先把最省时间的BUG先验证一遍。
BUG5:仍然无法重复你的结果
在I不赋初值得情况下,每次都显示零
版本是6.0.6.163/Window2000
我需要您的详细DELPHI版本号
 
AIMINGOO,能否麻烦你和我EMAIL联系,你提供的网址无法访问。
E:/>ping 202.102.247.230
Pinging 202.102.247.230 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Ping statistics for 202.102.247.230:
Packets: Sent = 4, Received = 0, Lost = 4 (100%
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
 
AIMINGOO
对不起,你所提的BUG1,4,5在我这里均无法重复,是否你用的D6版本有错误
BUG4:无法重复你的结果
每次都是显示
ConditionValue_1
版本是6.0.6.163/Window2000
代码
procedure TForm1.Button1Click(Sender: TObject);
var
MyIniFile: TIniFile;
s:string;
begin
begin
MyIniFile := TIniFile.Create('C:/_bugTemp/INIRepeatName/test.ini');
s := MyINiFile.ReadString('testSection','Condition','error');
showMessage(s);
MyIniFile.Free;
end;

运行结果
---------------------------
Project1
---------------------------
ConditionValue_1
---------------------------
OK
---------------------------
 
AMO,噢,谢谢你给我的JPG文件,另外,我可以问一下,能否的到你
在BUG4上的代码么? 看你上贴,你也遇到相同的问题,但我这里的结果
确一切正常。
并请告诉我你的D6的版本号码,谢谢
 
to y9y:
delphi6中的数据模块自动刷新也有问题
当在数据模块DATAMODULE中加入一个如ADOSTOREDPROC后,
使用datamodule.时,根本不会提示adostoredproc这一项,
要是强制加入为datamodule.adostoredproc后,编译提示
adostoredproc未定义
然而,把当前project关闭后再打开,就能够找到了
能告诉你的email吗,希望在以后使用delphi6的过程中遇过
问题能向你反映,以便解决。 OK?
我的email:xin_jian@21cn.com
 
y9y兄
在英文win2000(sp2)下帮助文件中能够使用find功能
但在中文win2000及中文win98下无此功能
是否和windows中hh.exe的版本有关?
sorry,此问题和您负责的VCL无关
我仅仅是好奇
 
提Bug居然还有分,你是最美地...。
Bug多多,也许是d版的问题。
 
哦!我这就装上D6,一个个地再测试吧~~~~~~~~~~~
我的mail : aim@263.net
不过来信的标题最好写明白点,我很会砍信的哦!哈哈~~~~~~~~
 
我重新测试了一下Bug1,4,6,7。
其中Bug4的描述有错误,事实上,是对TMemIniFile的处理有问题,而不是TIniFile。
此外,Bug6的问题我无法再重现了,但我的确在D5中遇到过这个问题,我想我会再留意它。
我将Bug1,4,7的测试代码打包上传了,有兴趣的话,可以去下载:
http://202.102.247.230/soft/BugTest.zip
如果下载不了,请给我Mail。
我的系统配置和y9y一样:
版本是6.0.6.163/Window2000
 
借用一下,我用的是d6,当我用adoquery向sql server数据库中插入数据时,
当有日期型时,一定会出错,我不知道这是不是bug,我是初学者,
to y9y,你既然是负责vcl的,你这个情况你遇到过没有
 
等着y9y给我个回信儿,也等着borland出sp~~~~~~~
:(~~~~~~~~~
 
接受答案了.
 
后退
顶部