fix(android): l'exception etait lue apres sa liberation

Register et Login mettaient leur gestionnaire d'erreur en file avec
TThread.Queue, puis y lisaient E.ClassName et E.Message. Or la file
s'execute sur le thread principal bien apres que le except a rendu la
main, et Delphi libere E en sortant du gestionnaire : c'etait une lecture
apres liberation.

Elle rendait un message vide - "Login failed: EPMACrypto - " sans la
raison - et parfois une violation d'acces qui remontait a FMX sans rien
laisser au journal. Le vrai motif de l'echec n'a donc jamais ete affiche.

On ne met plus en file que des chaines, qui survivent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-08-28 16:46:24 +01:00
parent 4e0223bee5
commit 5cc80727d6
+52 -10
View File
@@ -1935,13 +1935,24 @@ begin
end);
except
on E: Exception do
begin
// LE TEXTE EST PRIS ICI, PAS DANS LA FILE.
//
// TThread.Queue s'execute sur le thread principal bien apres que le
// except a rendu la main - et Delphi libere l'objet E en sortant du
// gestionnaire. Lire E.Message depuis la file etait donc une lecture
// apres liberation : elle rendait un message vide, et parfois une
// violation d'acces qui remontait a FMX sans rien laisser au journal.
// On ne met en file que des chaines, qui, elles, survivent.
var LWhy := E.ClassName + ' - ' + E.Message;
TThread.Queue(nil,
procedure
begin
SetBusy(False);
Log('Register failed: ' + E.ClassName + ' - ' + E.Message);
Log('Register failed: ' + LWhy);
StatusErr('Could not create the vault - see log');
end);
end;
end;
end).Start;
end;
@@ -1978,7 +1989,9 @@ begin
begin
try
FVaultPwd := APwd; // avant l'ouverture : c'est lui qui la fait
Log('login: opening the local container');
LPlain := OpenContainer(LoadLocalContainer, APwd);
Log(Format('login: opened, %d chars', [Length(LPlain)]));
LOwner := '';
LDoc := TJSONObject.ParseJSONValue(LPlain) as TJSONObject;
if LDoc <> nil then
@@ -1994,30 +2007,59 @@ begin
TThread.Queue(nil, procedure
begin Log('Vault belongs to ' + LOwner + ', not ' + AUser); end);
Log('login: writing the cache');
SaveVault(LPlain, FETag, APwd, BiometricAvailable, False, FPinSealed,
FKey, FKeySalt, FKeyIters);
Log('login: cache written');
TThread.Queue(nil,
procedure
begin
SetBusy(False);
if LOwner <> '' then FUser := LOwner else FUser := AUser;
// Meme regle qu'a la creation : ce mot de passe ouvre le conteneur
// local et s'arrete la.
FVaultPwd := APwd;
AdoptVault(LPlain);
// LE RETOUR SUR LE THREAD PRINCIPAL N'EST GARDE PAR RIEN, et c'est
// le seul endroit du chemin qui ne l'etait pas : ni le except du
// thread, ni celui du pont ne le couvrent - il s'execute bien apres
// que les deux ont rendu la main. Une faute ici remontait donc a
// FMX, qui montrait "Access violation" pendant que le journal
// s'arretait sans un mot.
try
Log('login: adopting');
SetBusy(False);
if LOwner <> '' then FUser := LOwner else FUser := AUser;
// Meme regle qu'a la creation : ce mot de passe ouvre le
// conteneur local et s'arrete la.
FVaultPwd := APwd;
AdoptVault(LPlain);
Log('login: done');
except
on E: Exception do
begin
SetBusy(False);
Log('login: adopt FAILED: ' + E.ClassName + ' - ' + E.Message);
StatusErr('Could not display the vault - see log');
end;
end;
end);
except
on E: Exception do
begin
// LE TEXTE EST PRIS ICI, PAS DANS LA FILE.
//
// TThread.Queue s'execute sur le thread principal bien apres que le
// except a rendu la main - et Delphi libere l'objet E en sortant du
// gestionnaire. Lire E.Message depuis la file etait donc une lecture
// apres liberation : elle rendait un message vide, et parfois une
// violation d'acces qui remontait a FMX sans rien laisser au journal.
// On ne met en file que des chaines, qui, elles, survivent.
var LWhy := E.ClassName + ' - ' + E.Message;
TThread.Queue(nil,
procedure
begin
SetBusy(False);
Log('Login failed: ' + E.ClassName + ' - ' + E.Message);
Log('Login failed: ' + LWhy);
// GCM echoue a sa verification quand la cle est fausse, et son
// message ne le dit pas. Le cas de loin le plus frequent.
Status('Wrong master password');
StatusErr('Wrong master password');
end);
end;
end;
end).Start;
end;