Indy的bug真让人受不了,遇到一个没有经过编码的中文邮件,比如:
Return-Path: <sdhuahan@public.qd.sd.cn>
Delivered-To: sdhuahan@public.qd.sd.cn
Received: from unknown (helo xxh)(unknown@221.0.203.213)
by ws02 with SMTP; Thu, 08 Apr 2010 06:36:15 +0000
X-Lasthop: 221.0.203.213
Date: Thu, 8 Apr 2010 14:36:25 +0800
From: "sdhuahan" <sdhuahan@public.qd.sd.cn>
To: "sdhuahan" <sdhuahan@public.qd.sd.cn>
Subject: 你好
Message-ID: <201004081436258007065@public.qd.sd.cn>
X-mailer: Foxmail 6, 15, 201, 22 [cn]
在测试您的 SMTP 设置时, Foxmail 会自动发送该电子邮件。
这个邮件在Indy接收时主题和正文都会乱码,只得再次追踪,发现问题在IdGlobal中,第5190行开始:
代码
1 function BytesToString(const AValue: TIdBytes; const AStartIndex: Integer;
2 const ALength: Integer = -1; AEncoding: TIdTextEncoding = nil): string; overload;
3 var
4 LLength: Integer;
5 {$IFNDEF DOTNET_OR_UNICODESTRING}
6 LBytes: TIdBytes;
7 {$ENDIF}
8 begin
9 {$IFNDEF DOTNET_OR_UNICODESTRING}
10 LBytes := nil; // keep the compiler happy
11 {$ENDIF}
12 LLength := IndyLength(AValue, ALength, AStartIndex);
13 if LLength > 0 then begin
14
15 //add by garfield,2010.04.09
16 //begin*************
17 AEncoding:=nil;
18 TEncoding.GetBufferEncoding(AValue,AEncoding);
19 //end*************
20 EnsureEncoding(AEncoding);
21 {$IFDEF DOTNET_OR_UNICODESTRING}
22 Result := AEncoding.GetString(AValue, AStartIndex, LLength);
23 {$ELSE}
24 LBytes := TIdTextEncoding.Convert(
25 AEncoding,
26 Indy8BitEncoding,
27 AValue, AStartIndex, LLength);
28 SetString(Result, PAnsiChar(LBytes), Length(LBytes));
29 {$ENDIF}
30 end else begin
31 Result := '';
32 end;
33 end;
34
2 const ALength: Integer = -1; AEncoding: TIdTextEncoding = nil): string; overload;
3 var
4 LLength: Integer;
5 {$IFNDEF DOTNET_OR_UNICODESTRING}
6 LBytes: TIdBytes;
7 {$ENDIF}
8 begin
9 {$IFNDEF DOTNET_OR_UNICODESTRING}
10 LBytes := nil; // keep the compiler happy
11 {$ENDIF}
12 LLength := IndyLength(AValue, ALength, AStartIndex);
13 if LLength > 0 then begin
14
15 //add by garfield,2010.04.09
16 //begin*************
17 AEncoding:=nil;
18 TEncoding.GetBufferEncoding(AValue,AEncoding);
19 //end*************
20 EnsureEncoding(AEncoding);
21 {$IFDEF DOTNET_OR_UNICODESTRING}
22 Result := AEncoding.GetString(AValue, AStartIndex, LLength);
23 {$ELSE}
24 LBytes := TIdTextEncoding.Convert(
25 AEncoding,
26 Indy8BitEncoding,
27 AValue, AStartIndex, LLength);
28 SetString(Result, PAnsiChar(LBytes), Length(LBytes));
29 {$ENDIF}
30 end else begin
31 Result := '';
32 end;
33 end;
34
不知道AEncoding变量为什么有问题,我采用了上面简单的办法,可以正确解码了,不知道大侠有没有更彻底的解决办法。