Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending the UTF8 command to the POP3 Server #450

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Lib/Protocols/IdPOP3.pas
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,18 @@ procedure TIdPOP3.SetSASLMechanisms(AValue: TIdSASLEntries);
FSASLMechanisms.Assign(AValue);
end;

procedure TIdPOP3.SendUTF8IfAdvertised;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really liking the naming of this method. If you look at other Indy components, they use more general-purpose methods for testing for available capabilties (eg, TIdNNTP.IsExtCmdSupported(), TIdDICT.IsCapaSupported(), TIdFTP.IsExtSupported(), etc). I think your method needs to look a little more like TIdFTP.FindAuthCmd(), for example.

var
Capa : string;
begin
for Capa in FCapabilities do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indy cannot use for..in loops, as it still supports older compilers.

if TextStartsWith(Capa, 'UTF8 ') then
Copy link
Member

@rlebeau rlebeau Mar 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UTF8 capability has an optional USER argument. If that argument is not present, the trailing space is likely to also not be present, which would cause this TextStartsWith() call to return False. You can use IdGlobal.Fetch() to retrieve the first word from the Capa string before then comparing it.

begin
SendCmd('UTF8','');
exit;
end;
end;

procedure TIdPOP3.Connect;
var
S: String;
Expand Down Expand Up @@ -619,6 +631,7 @@ procedure TIdPOP3.Connect;
if FAutoLogin then begin
Login;
end;
SendUTF8IfAdvertised;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sending the UTF8 command at this location is a Catch-22. AutoLogin is True by default, so you would typically be sending the UTF8 command after Login() has already sent the STLS and USER/PASS/APOP/AUTH commands, which is too late for sending UTF-8 encoded authentication. On the other hand, the UTF8 command is not allowed to be sent before an STLS command, so you can't just move the call before Login().

So, you are going to have to move the UTF8 command inside of Login() itself instead, so that Login() can send the UTF8 command after sending the STLS command and before sending the USER/PASS/APOP/AUTH commands. If AutoLogin is False, Connect() should not send UTF8 at all, as that would then prevent a later call to Login() from sending the STLS command.

The alternative would be to manually keep track of whether TIdPOP3 is currently operating in ASCII or UTF8 mode and then send the UTF8 command only when absolutely necessary for a subsequent command to use UTF-8.

except
Disconnect(False);
raise;
Expand Down