Fix the other use after free

This commit is contained in:
Learath 2017-10-17 15:39:20 +02:00
parent 7f8356e37e
commit 96acddb57f
6 changed files with 32 additions and 13 deletions

View file

@ -15,7 +15,6 @@ class CFetchTask : public IFetchTask
friend class CFetcher; friend class CFetcher;
class CFetcher *m_pFetcher; class CFetcher *m_pFetcher;
CJob m_Job;
CURL *m_pHandle; CURL *m_pHandle;
void *m_pUser; void *m_pUser;
@ -35,6 +34,7 @@ class CFetchTask : public IFetchTask
bool m_Abort; bool m_Abort;
bool m_Destroy; bool m_Destroy;
bool m_PastCB;
public: public:
virtual double Current() { return m_Current; } virtual double Current() { return m_Current; }
@ -49,7 +49,7 @@ public:
void CFetchTask::Destroy() void CFetchTask::Destroy()
{ {
if(m_Job.Status() == CJob::STATE_DONE) if(m_PastCB)
{ {
delete this; delete this;
} }
@ -76,6 +76,18 @@ void CFetcher::Escape(char *pBuf, size_t size, const char *pStr)
curl_free(pEsc); curl_free(pEsc);
} }
void CFetcher::DestroyCallback(CJob *pJob, void *pUser)
{
CFetchTask *pTask = (CFetchTask *)pUser;
delete pJob;
if(pTask->m_Destroy)
delete pTask;
pTask->m_PastCB = true;
}
IFetchTask *CFetcher::FetchFile(const char *pUrl, const char *pDest, int StorageType, bool UseDDNetCA, bool CanTimeout, void *pUser, COMPFUNC pfnCompCb, PROGFUNC pfnProgCb) IFetchTask *CFetcher::FetchFile(const char *pUrl, const char *pDest, int StorageType, bool UseDDNetCA, bool CanTimeout, void *pUser, COMPFUNC pfnCompCb, PROGFUNC pfnProgCb)
{ {
CFetchTask *pTask = new CFetchTask; CFetchTask *pTask = new CFetchTask;
@ -92,10 +104,13 @@ IFetchTask *CFetcher::FetchFile(const char *pUrl, const char *pDest, int Storage
pTask->m_Abort = false; pTask->m_Abort = false;
pTask->m_Destroy = false; pTask->m_Destroy = false;
pTask->m_PastCB = false;
pTask->m_Size = pTask->m_Progress = 0; pTask->m_Size = pTask->m_Progress = 0;
pTask->m_State = IFetchTask::STATE_QUEUED; pTask->m_State = IFetchTask::STATE_QUEUED;
m_pEngine->AddJob(&pTask->m_Job, FetcherThread, pTask);
CJob *pJob = new CJob;
m_pEngine->AddJob(pJob, FetcherThread, pTask, DestroyCallback);
return pTask; return pTask;
} }
@ -180,9 +195,6 @@ int CFetcher::FetcherThread(void *pUser)
if(pTask->m_pfnCompCallback) if(pTask->m_pfnCompCallback)
pTask->m_pfnCompCallback(pTask, pTask->m_pUser); pTask->m_pfnCompCallback(pTask, pTask->m_pUser);
if(pTask->m_Destroy)
delete pTask;
return(ret != CURLE_OK) ? 1 : 0; return(ret != CURLE_OK) ? 1 : 0;
} }

View file

@ -15,6 +15,7 @@ public:
virtual IFetchTask *FetchFile(const char *pUrl, const char *pDest, int StorageType = -2, bool UseDDNetCA = false, bool CanTimeout = true, void *pUser = 0, COMPFUNC pfnCompCb = 0, PROGFUNC pfnProgCb = 0); virtual IFetchTask *FetchFile(const char *pUrl, const char *pDest, int StorageType = -2, bool UseDDNetCA = false, bool CanTimeout = true, void *pUser = 0, COMPFUNC pfnCompCb = 0, PROGFUNC pfnProgCb = 0);
virtual void Escape(char *pBud, size_t size, const char *pStr); virtual void Escape(char *pBud, size_t size, const char *pStr);
static void DestroyCallback(CJob *pJob, void *pUser);
static int FetcherThread(void *pUser); static int FetcherThread(void *pUser);
static size_t WriteToFile(char *pData, size_t size, size_t nmemb, void *pFile); static size_t WriteToFile(char *pData, size_t size, size_t nmemb, void *pFile);
static int ProgressCallback(void *pUser, double DlTotal, double DlCurr, double UlTotal, double UlCurr); static int ProgressCallback(void *pUser, double DlTotal, double DlCurr, double UlTotal, double UlCurr);

View file

@ -26,7 +26,7 @@ public:
virtual void Init() = 0; virtual void Init() = 0;
virtual void InitLogfile() = 0; virtual void InitLogfile() = 0;
virtual void HostLookup(CHostLookup *pLookup, const char *pHostname, int Nettype) = 0; virtual void HostLookup(CHostLookup *pLookup, const char *pHostname, int Nettype) = 0;
virtual void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData) = 0; virtual void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCB = 0) = 0;
}; };
extern IEngine *CreateEngine(const char *pAppname, bool Silent); extern IEngine *CreateEngine(const char *pAppname, bool Silent);

View file

@ -106,11 +106,11 @@ public:
AddJob(&pLookup->m_Job, HostLookupThread, pLookup); AddJob(&pLookup->m_Job, HostLookupThread, pLookup);
} }
void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData) void AddJob(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCB = 0)
{ {
if(g_Config.m_Debug) if(g_Config.m_Debug)
dbg_msg("engine", "job added"); dbg_msg("engine", "job added");
m_JobPool.Add(pJob, pfnFunc, pData); m_JobPool.Add(pJob, pfnFunc, pData, pfnCB);
} }
}; };

View file

@ -53,6 +53,8 @@ void CJobPool::WorkerThread(void *pUser)
pJob->m_Status = CJob::STATE_RUNNING; pJob->m_Status = CJob::STATE_RUNNING;
pJob->m_Result = pJob->m_pfnFunc(pJob->m_pFuncData); pJob->m_Result = pJob->m_pfnFunc(pJob->m_pFuncData);
pJob->m_Status = CJob::STATE_DONE; pJob->m_Status = CJob::STATE_DONE;
if(pJob->m_pfnCallback)
pJob->m_pfnCallback(pJob, pJob->m_pFuncData);
} }
} }
@ -67,11 +69,12 @@ int CJobPool::Init(int NumThreads)
return 0; return 0;
} }
int CJobPool::Add(CJob *pJob, JOBFUNC pfnFunc, void *pData) int CJobPool::Add(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCallback)
{ {
mem_zero(pJob, sizeof(CJob)); mem_zero(pJob, sizeof(CJob));
pJob->m_pfnFunc = pfnFunc; pJob->m_pfnFunc = pfnFunc;
pJob->m_pFuncData = pData; pJob->m_pFuncData = pData;
pJob->m_pfnCallback = pfnCallback;
lock_wait(m_Lock); lock_wait(m_Lock);

View file

@ -2,10 +2,12 @@
/* If you are missing that file, acquire a complete release at teeworlds.com. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef ENGINE_SHARED_JOBS_H #ifndef ENGINE_SHARED_JOBS_H
#define ENGINE_SHARED_JOBS_H #define ENGINE_SHARED_JOBS_H
typedef int (*JOBFUNC)(void *pData); class CJob;
class CJobPool; class CJobPool;
typedef int (*JOBFUNC)(void *pData);
typedef void (*CBFUNC)(CJob *pJob, void *pData);
class CJob class CJob
{ {
friend class CJobPool; friend class CJobPool;
@ -17,6 +19,7 @@ class CJob
volatile int m_Result; volatile int m_Result;
JOBFUNC m_pfnFunc; JOBFUNC m_pfnFunc;
CBFUNC m_pfnCallback;
void *m_pFuncData; void *m_pFuncData;
public: public:
CJob() CJob()
@ -58,6 +61,6 @@ public:
~CJobPool(); ~CJobPool();
int Init(int NumThreads); int Init(int NumThreads);
int Add(CJob *pJob, JOBFUNC pfnFunc, void *pData); int Add(CJob *pJob, JOBFUNC pfnFunc, void *pData, CBFUNC pfnCallback = 0);
}; };
#endif #endif