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;
class CFetcher *m_pFetcher;
CJob m_Job;
CURL *m_pHandle;
void *m_pUser;
@ -35,6 +34,7 @@ class CFetchTask : public IFetchTask
bool m_Abort;
bool m_Destroy;
bool m_PastCB;
public:
virtual double Current() { return m_Current; }
@ -49,7 +49,7 @@ public:
void CFetchTask::Destroy()
{
if(m_Job.Status() == CJob::STATE_DONE)
if(m_PastCB)
{
delete this;
}
@ -76,6 +76,18 @@ void CFetcher::Escape(char *pBuf, size_t size, const char *pStr)
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)
{
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_Destroy = false;
pTask->m_PastCB = false;
pTask->m_Size = pTask->m_Progress = 0;
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;
}
@ -180,9 +195,6 @@ int CFetcher::FetcherThread(void *pUser)
if(pTask->m_pfnCompCallback)
pTask->m_pfnCompCallback(pTask, pTask->m_pUser);
if(pTask->m_Destroy)
delete pTask;
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 void Escape(char *pBud, size_t size, const char *pStr);
static void DestroyCallback(CJob *pJob, void *pUser);
static int FetcherThread(void *pUser);
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);

View file

@ -26,7 +26,7 @@ public:
virtual void Init() = 0;
virtual void InitLogfile() = 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);

View file

@ -106,11 +106,11 @@ public:
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)
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_Result = pJob->m_pfnFunc(pJob->m_pFuncData);
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;
}
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));
pJob->m_pfnFunc = pfnFunc;
pJob->m_pFuncData = pData;
pJob->m_pfnCallback = pfnCallback;
lock_wait(m_Lock);

View file

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