Parcourir la source

Fix cover worker lifecycle and harden metadata extraction

- Avoid dangling thread pointer by managing worker FreeOnTerminate and freeing finished worker\n- Use PATH fallback for 'pdfinfo' and 'unzip' and catch execution errors\n- This ensures metadata/covers work reliably when tools are present in PATH
Codex CLI il y a 4 mois
Parent
commit
11d18eb868
2 fichiers modifiés avec 60 ajouts et 42 suppressions
  1. 9 3
      src/unitCoverWorker.pas
  2. 51 39
      src/unitmetadata.pas

+ 9 - 3
src/unitCoverWorker.pas

@@ -174,10 +174,16 @@ end;
 procedure CoverWorkerStart;
 begin
   EnsureQueue;
-  if (GWorker = nil) or (GWorker.Finished) then
+  // If a previous worker finished, free it before creating a new one
+  if Assigned(GWorker) and GWorker.Finished then
+  begin
+    GWorker.Free;
+    GWorker := nil;
+  end;
+  if (GWorker = nil) then
   begin
     GWorker := TCoverWorker.Create(True);
-    GWorker.FreeOnTerminate := True;
+    GWorker.FreeOnTerminate := False; // we manage lifecycle explicitly
     GWorker.Start;
   end;
 end;
@@ -196,7 +202,7 @@ begin
       Classes.CheckSynchronize(10);
       Sleep(5);
     end;
-    GWorker := nil;
+    FreeAndNil(GWorker);
   end;
   if GPdfQueue <> nil then
   begin

+ 51 - 39
src/unitmetadata.pas

@@ -29,25 +29,29 @@ begin
   Title := '';
   Authors := '';
   exe := FindDefaultExecutablePath('pdfinfo');
-  if exe = '' then Exit;
+  if exe = '' then exe := 'pdfinfo';
   proc := TProcess.Create(nil);
   sl := TStringList.Create;
   try
-    proc.Executable := exe;
-    proc.Parameters.Add(FileName);
-    proc.Options := [poWaitOnExit, poUsePipes];
-    proc.ShowWindow := swoHide;
-    proc.Execute;
-    sl.LoadFromStream(proc.Output);
-    for i := 0 to sl.Count - 1 do
-    begin
-      line := sl[i];
-      if (Title = '') and AnsiStartsStr('Title:', line) then
-        Title := Trim(Copy(line, 7, MaxInt));
-      if (Authors = '') and (AnsiStartsStr('Author:', line) or AnsiStartsStr('Authors:', line)) then
-        Authors := Trim(Copy(line, Pos(':', line) + 1, MaxInt));
+    try
+      proc.Executable := exe;
+      proc.Parameters.Add(FileName);
+      proc.Options := [poWaitOnExit, poUsePipes];
+      proc.ShowWindow := swoHide;
+      proc.Execute;
+      sl.LoadFromStream(proc.Output);
+      for i := 0 to sl.Count - 1 do
+      begin
+        line := sl[i];
+        if (Title = '') and AnsiStartsStr('Title:', line) then
+          Title := Trim(Copy(line, 7, MaxInt));
+        if (Authors = '') and (AnsiStartsStr('Author:', line) or AnsiStartsStr('Authors:', line)) then
+          Authors := Trim(Copy(line, Pos(':', line) + 1, MaxInt));
+      end;
+      Result := (Title <> '') or (Authors <> '');
+    except
+      Result := False;
     end;
-    Result := (Title <> '') or (Authors <> '');
   finally
     sl.Free;
     proc.Free;
@@ -69,27 +73,31 @@ begin
   Title := '';
   Authors := '';
   exe := FindDefaultExecutablePath('unzip');
-  if exe = '' then Exit;
+  if exe = '' then exe := 'unzip';
   // list files
   proc := TProcess.Create(nil);
   sl := TStringList.Create;
   try
-    proc.Executable := exe;
-    proc.Parameters.Add('-Z1');
-    proc.Parameters.Add(FileName);
-    proc.Options := [poWaitOnExit, poUsePipes];
-    proc.ShowWindow := swoHide;
-    proc.Execute;
-    sl.LoadFromStream(proc.Output);
-    opfPath := '';
-    for i := 0 to sl.Count - 1 do
-    begin
-      line := Trim(sl[i]);
-      if LowerCase(ExtractFileExt(line)) = '.opf' then
+    try
+      proc.Executable := exe;
+      proc.Parameters.Add('-Z1');
+      proc.Parameters.Add(FileName);
+      proc.Options := [poWaitOnExit, poUsePipes];
+      proc.ShowWindow := swoHide;
+      proc.Execute;
+      sl.LoadFromStream(proc.Output);
+      opfPath := '';
+      for i := 0 to sl.Count - 1 do
       begin
-        opfPath := line;
-        Break;
+        line := Trim(sl[i]);
+        if LowerCase(ExtractFileExt(line)) = '.opf' then
+        begin
+          opfPath := line;
+          Break;
+        end;
       end;
+    except
+      opfPath := '';
     end;
   finally
     sl.Free;
@@ -100,15 +108,19 @@ begin
   proc := TProcess.Create(nil);
   stream := TStringStream.Create('');
   try
-    proc.Executable := exe;
-    proc.Parameters.Add('-p');
-    proc.Parameters.Add(FileName);
-    proc.Parameters.Add(opfPath);
-    proc.Options := [poWaitOnExit, poUsePipes];
-    proc.ShowWindow := swoHide;
-    proc.Execute;
-    stream.CopyFrom(proc.Output, 0);
-    stream.Position := 0;
+    try
+      proc.Executable := exe;
+      proc.Parameters.Add('-p');
+      proc.Parameters.Add(FileName);
+      proc.Parameters.Add(opfPath);
+      proc.Options := [poWaitOnExit, poUsePipes];
+      proc.ShowWindow := swoHide;
+      proc.Execute;
+      stream.CopyFrom(proc.Output, 0);
+      stream.Position := 0;
+    except
+      stream.Size := 0;
+    end;
   finally
     proc.Free;
   end;