Hinweis: ======== Das Archiv enthält zwei Bugfixe für Hamster 2.1.0.11: - bestimmte fehlerhafte Ausdrücke im Scorefile erzeugen Abstürze - syntaxtisch falsche Adressen im Envelope-From wurden zu dummy Um diese Version zu benutzen, muß vorher der Hamster 2.1.0.11 installiert werden, zu finden auf der Homepage von Thomas G. Liesner (http://www. tglsoft.de/). Anschließend ist die Datei hamster.exe mit der aus diesem Archiv zu ersetzen. Wer die Möglichkeit hat, kann sich natürlich auch seinen eigenen Hamster mit den unten genannten Änderungen compilieren. ############################################################################ # # # Bugfix 1 # # # ############################################################################ Der Hamster extrahiert in verschiedenen Situationen die eMail-Adresse aus einem From: oder To: - Header bzw. prüft die korrekte Syntax. Dabei wurde, falls er keine eMail-Adresse finden konnte, dummy als Ergebnis zurückgegeben. Die folgende Fassung der Funktion FilterEmailOfFrom aus uTools.pas ist weniger anfällig für defekte/ungültige eMail-Adressen: function FilterEmailOfFrom(From:String):String; //HRR //------------------------------------------------------------------------------ function extract(Limiter:String; var FullString,PartString:String):Boolean; var p1,p2,i : Integer; quoted : Boolean; begin result:=False; repeat p1:=0; p2:=0; for i:=1 to length(FullString) do begin if ((FullString[i]=Limiter[1]) and (p2=0)) or ((FullString[i]=Limiter[2]) and (p2<>0)) then begin quoted:=false; if i>1 then if fullstring[i-1]='\' then quoted:=True; if not quoted then begin p1:=p2; p2:=i; if p1<>0 then break; end; end; end; if (p2<>0) and (p1=0) then begin FullString:=Fullstring+limiter[2]; p1:=p2; p2:=length(FullString) end; if p1<>0 then begin result:=True; PartString:=copy(FullString,p1+1,p2-p1-1); system.Delete(FullString,p1,p2-p1+1); end; until p1=0; end; //------------------------------------------------------------------------------ var erg : String; s1,s2 : String; i : Integer; begin Erg:=From; Extract('""',Erg,s1); //delete all between "..." Extract('()',Erg,s1); //delete all between (...) s1:=erg; if extract('<>',s1,s2) then //eMail found between <..> erg:=s2 ; i:=1; while i<=length(erg) do begin if (erg[i]=' ') or (erg[i]=#9) then system.Delete(Erg,i,1) else inc(i); ; end; result:=erg; end; ############################################################################ # # # Bugfix 2 # # # ############################################################################ Der Hamster 2.1.0.11 hat bei fehlerhaften numerischen Ausdrücken wie =-10 xpost: %2 Probleme. Mit dem folgenden Fix werden zwei damit zusammenhängende Fehler im Filter behoben und die Meldungen präzisiert: a) Der Test der Scorefile-Syntax während des Hamsterstarts kontroliert numerische Ausdrücke strenger. b) Exceptions, die beim Pull während der Auswertung einer Filterzeile auftreten, stoppen nicht mehr den ganzen Thread sondern bewerten die betreffende Filterzeile als nicht matchend. Die entsprechenden Änderungen sind jeweils mit //HR 2006-11 gekennzeichnet und betreffen folgende Stellen: ------------------------------------------------------------------------------ Ein fehlender Vergleichsoperator löst in cFilerBase.pas, TFilterPatternBase.Create jetzt eine Exception aus: constructor TFilterPatternBase.Create(ASelectType: Char; APatternType: TPatterntype; APattern: String); ... If Length(s)>2 then begin If UpCase(s[Length(s)])='B' then Delete(s, Length(s), 1); Case UpCase(s[Length(s)]) of 'K': begin Faktor := 1024; Delete(s, Length(s), 1) end; 'M': begin Faktor := 1024*1024; Delete(s, Length(s), 1) end; end; end; if PatternStr = '' then begin //HR 2006-11 start ErrorShowed := true; raise Exception.Create('Error in filter-pattern: missing operator in "'+APattern+'"'); end; //HR 2006-11 end Val(s, x, E); If E = 0 then begin PatternValue := x * Faktor end else begin ErrorShowed := true; raise Exception.Create('Error in filter-pattern: "'+org+'" is not a valid numeric pattern'); end end; end; ------------------------------------------------------------------------------ In cFilterNews.pas, TFilterLineNews.MatchesData wird eine Exception während des Auswertens des Filterausdrucks als nicht matchender Ausdruck gewertet, d. h. die Filterzeile wird ignoriert: function TFilterLineNews.MatchesData( const RE: TPCRE; // PG FilterData: TFilterDataBase ): Boolean; // PG const ONE=0; YES=1; NO=2; var Pat : TFilterPatternNews; TestStr, DefStr : String; NeedOneOf, HaveOneOf: Boolean; PatNo: Integer; Matches : Boolean; begin try //HR: 2006-11 Result := True; DefStr := FilterData.GetValue( XOverField, XFiltField, DoMimeDecode ); // PG NeedOneOf := False; HaveOneOf := False; for PatNo:=0 to PatternCount-1 do begin Pat := TFilterPatternNews( PatternItem[ PatNo ] ); if Pat.IsSameField then TestStr := DefStr else TestStr := FilterData.GetValue( Pat.XOverField, Pat.XFiltField, DoMimeDecode ); if (Pat.SelectType<>' ') or not(HaveOneOf) then begin Matches := Pat.Matches(Pat.PatternStr, TestStr, RE); case Pat.SelectType of '+': if not Matches then begin Result:=False; break; end; '-': if Matches then begin Result:=False; break; end; ' ': begin NeedOneOf := True; if Matches then HaveOneOf:=True; end; end; end; end; if NeedOneOf and not HaveOneOf then Result:=False; If Unless then Result := Not Result except //HR: 2006-11 start on e:Exception do begin Log( LOGID_WARN, 'Scorefile.InternalError.MatchesData2', 'internal error in scoreline [%s]: %s', [fOrgLineText,e.Message]); result:=false; end; end; //HR: 2006-11 end end; ------------------------------------------------------------------------------ In cFilterNews.pas, TFilterLineNews.SetFilterLine (ungefähr Zeilen 650) wird eine Exception während des Auswerten des Vergleichpatterns als Syntaxfehler gewertet und nicht mehr als "Internal Error" (passierte z. B. wegen den überflüssigen Leerzeichen in "-10 xref: % > 3"): Case StopChar of '}': PatTyp := ptRegExp; '"', '$': PatTyp := ptString; '''': PatTyp := ptExactString; else begin If s = '*' then PatTyp := ptWildcard else If Copy(s, 1, 1)='%' then PatTyp := ptValue; end end; try //HR 2006-11 start pat := TFilterPatternNews.Create(TmpSelectType, PatTyp, s); If TmpFilterHeader > '' then begin if IsBeforeLoad then begin // PG TempXOverField := XFieldNameToNumber( TmpFilterHeader ); // PG if TempXOverField=XOVER_INVALID then begin err := 'invalid field "'+TmpFilterHeader+'"'; break end end else begin // PG TempXFiltField := LowerCase(TmpFilterHeader) end end; pat.IsSameField := TmpFilterHeader = ''; pat.XOverField := TempXOverField; // PG pat.XFiltField := TempXFiltField; // PG PatternAdd( pat ); except on e:Exception do Err:=e.Message; end; //HR 2006-11 end end; InitPattern end end; end; If Err>'' then break ------------------------------------------------------------------------------ In cFilterNews.pas, DoLine wurde der Fehlerzähler manchmal nicht erhöht: procedure DoLine (Const Filterfilename: String; Const LineNo: Integer; Linetext: String); var j, k: Integer; s: String; ok: Boolean; Error: String; begin if IsFilterLine( LineText ) then begin // filter-line if Not GroupOK then begin Log( kGlobal, LOGID_WARN, 'TestFilterFile.Ignored.Info', 'Filterfile "%s", line %s will be ignored: %s', [FilterFileName, IntToStr(LineNo), LineText]); s := TrGl(kGlobal, 'TestFilterFile.Ignored.Reason.NoGroup', 'No legal Grouppattern was defined above'); Log( kGlobal, LOGID_WARN, 'TestFilterFile.Ignored.Reason', 'Reason: %s', s); inc(counter); //HR 2006-11 end else begin With TFilterLineNews.Create do try If Not SetFilterLine( Filterfilename, LineNo, LineText ) then begin Log( kGlobal, LOGID_WARN, 'TestFilterFile.HasError.Info', 'Filterfile "%s", line %s will be ignored: %s', [FilterFileName, IntToStr(LineNo), LineText]); Log( kGlobal, LOGID_WARN, 'TestFilterFile.HasError.Reason', 'Reason: %s', LastError ); inc(counter); //HR 2006-11 end finally Free end end; Exit end; ------------------------------------------------------------------------------ In cFilerNews.pas, TFiltersNews.Test enthält die Fehlermeldung "Internal Error" jetzt die betreffende Scorefilezeile: Var i: Integer; Line: String; begin If fFilterFile.Count = 0 then Exit; Counter := 0; Log( LOGID_SYSTEM, 'Scorefile.Testing', 'Testing news-score-file'); try GroupOK := False; With fFilterFile do begin for i:=0 to Count-1 do begin Line := TrimWhSpace( Lines[i] ); If Line > '' then DoLine(Filename[i], LineNr[i], Line) end end except On E:Exception do Log( LOGID_WARN, 'Scorefile.Testing.InternalError2', 'Internal error when testing Score-File-Line [%s]: %s', [Line,E.Message] ) //HR 2006-11 end; If Counter = 0 then Log( LOGID_INFO, 'Scorefile.Testing.OK', 'News-score-file: Test OK') else Log( LOGID_SYSTEM, 'Scorefile.Testing.ErrorsFound', 'News-score-file: %s errors found', IntToStr(Counter)); end;