/* "Spam Filter"-Plugin for Miranda IM Copyright 2003-2006 Heiko Herkenrath This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program ("SpamFilter-License.txt"); if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // -- Defines //#define DISABLE_REGEXP_SUPPORT // -- Includes #include "common.h" #include "Utilities/PCRE/include/pcre.h" // -- Variables HMODULE hPcreDLL = NULL; // -- Function Pointers int (*dyn_pcre_config)(int, void*); pcre* (*dyn_pcre_compile)(const char*, int, const char**, int*, const unsigned char*); pcre_extra* (*dyn_pcre_study)(const pcre*, int, const char **); int (*dyn_pcre_exec)(const pcre*, const pcre_extra*, const char*, int, int, int, int*, int); void (**dyn_pointer_pcre_free)(void*); #define dyn_pcre_free (*dyn_pointer_pcre_free); // ----------------------------------------- BOOL RegExpExistsInString(const WCHAR* pszString, const WCHAR* pszRegEx, BOOL bCaseSensitive, BOOL* pbRegExMalformed) { if (pbRegExMalformed) *pbRegExMalformed = FALSE; if (!pszString || !pszRegEx) return FALSE; if (hPcreDLL) { int iRc; pcre* pPcre; pcre_extra* pExtra; // Following are dummy buffers that are needed for the functions to work const char* pszErr; int iErrOffset; // 1.) Interpret regular expression #if defined(UNICODE) { char* pszRegExUtf8 = mir_utf8encodeW(pszRegEx); if (pszRegExUtf8) { pPcre = dyn_pcre_compile(pszRegExUtf8, (bCaseSensitive ? 0 : PCRE_CASELESS)|PCRE_UTF8|PCRE_NO_UTF8_CHECK, &pszErr, &iErrOffset, NULL); mir_free(pszRegExUtf8); } else { pPcre = NULL; } } #else pPcre = dyn_pcre_compile(pszRegEx, (bCaseSensitive ? 0 : PCRE_CASELESS), &pszErr, &iErrOffset, NULL); #endif if (pPcre) { // 2.) Study regular expression (not necessary) pExtra = dyn_pcre_study(pPcre, 0, &pszErr); // 3.) Search for regular expression #if defined(UNICODE) { char* pszStringUtf8 = mir_utf8encodeW(pszString); if (pszStringUtf8) { iRc = dyn_pcre_exec(pPcre, pExtra, (char*)pszStringUtf8, (int)lstrlenA(pszStringUtf8), 0, PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK, NULL, 0); mir_free(pszStringUtf8); } else { iRc = 0; } } #else iRc = dyn_pcre_exec(pPcre, pExtra, pszString, (int)lstrlen(pszString), 0, PCRE_NOTEMPTY, NULL, 0); #endif // Release memory dyn_pcre_free(pPcre); if (pExtra) dyn_pcre_free(pExtra); return (iRc >= 0); } else { if (pbRegExMalformed) *pbRegExMalformed = TRUE; #if !defined(_DEBUG) if (!pbRegExMalformed) #endif { WCHAR szOut[128]; mir_sntprintf(szOut, ARRAYSIZE(szOut), _T("Spam Filter: Syntax error in RegExp (%s).\r\n"), pszRegEx); OutputDebugString(szOut); } } } // Default string search (fallback) return (bCaseSensitive ? StrStr(pszString, pszRegEx) : StrStrI(pszString, pszRegEx)) ? TRUE : FALSE; } BOOL ValidateRegExp(const WCHAR* pszRegEx) { if (hPcreDLL) { pcre* pPcre; char* pszErr; int iErrOffset; // Parameter check if (!pszRegEx) return FALSE; // Interpret regular expression #if defined(UNICODE) { char* pszRegExUtf8 = mir_utf8encodeW(pszRegEx); if (pszRegExUtf8) { pPcre = dyn_pcre_compile(pszRegExUtf8, PCRE_UTF8|PCRE_NO_UTF8_CHECK, &pszErr, &iErrOffset, NULL); mir_free(pszRegExUtf8); } else { pPcre = NULL; } } #else pPcre = dyn_pcre_compile(pszRegEx, 0, &pszErr, &iErrOffset, NULL); #endif if (pPcre) { dyn_pcre_free(pPcre); // Release memory return TRUE; } else { return FALSE; } } else { return TRUE; } } BOOL RegExpEnabled(void) { return (hPcreDLL ? TRUE : FALSE); } // ------------------------------------ void InitRegExp(void) { #if !defined(DISABLE_REGEXP_SUPPORT) hPcreDLL = LoadLibrary(_T("PCRE")); if (hPcreDLL) { // Exported functions // GetProcAddress returns the pointer to the function *(FARPROC*)&dyn_pcre_config = GetProcAddress(hPcreDLL, "pcre_config"); *(FARPROC*)&dyn_pcre_compile = GetProcAddress(hPcreDLL, "pcre_compile"); *(FARPROC*)&dyn_pcre_study = GetProcAddress(hPcreDLL, "pcre_study"); *(FARPROC*)&dyn_pcre_exec = GetProcAddress(hPcreDLL, "pcre_exec"); // Exported variables // GetProcAddress returns the pointer to the variable containing the pointer to the function...jippieh! :-) *(FARPROC*)&dyn_pointer_pcre_free = GetProcAddress(hPcreDLL, "pcre_free"); if (dyn_pcre_compile && dyn_pcre_exec && dyn_pointer_pcre_free && (*dyn_pointer_pcre_free)) { #if defined(UNICODE) int iUtf8Supported = 0; if (dyn_pcre_config) dyn_pcre_config(PCRE_CONFIG_UTF8, &iUtf8Supported); if (iUtf8Supported != 0) return; #else return; #endif } // Error: Unloading FreeLibrary(hPcreDLL); hPcreDLL = NULL; } // Debug output OutputDebugString(_T("Spam Filter: RegExp DLL (PCRE.DLL) not found or not compatible.\r\n")); #else // Debug output OutputDebugString(_T("Spam Filter: RegExp support disabled.\r\n")); #endif } void UninitRegExp(void) { if (hPcreDLL) FreeLibrary(hPcreDLL); }