Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

corec: rework internals to avoid pointer alignment issues #204

Merged
merged 32 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a2ae032
libebml2: fix use after free on CRC reading error
robUx4 Jan 3, 2025
7488c94
libebml2: pass the CRC data as void
robUx4 Jan 3, 2025
bec2a57
libmatroska2: count block data with ARRAYCOUNT()
robUx4 Jan 3, 2025
ab275ce
corec: make the string tab type fully private
robUx4 Jan 3, 2025
1f79410
corec: make ArraySize() private
robUx4 Jan 3, 2025
aad0993
corec: make DATA_FLAG_HEAP private
robUx4 Jan 3, 2025
99df83a
corec: make DATA_FLAG_MEMHEAP private
robUx4 Jan 3, 2025
c4189e8
corec: use ArrayInitEx() to clear memheap arrays
robUx4 Jan 3, 2025
b9f4076
corec: expand Data_Release() into Data_Clear()
robUx4 Jan 3, 2025
43b64fb
corec: reorder Data_Clear()
robUx4 Jan 3, 2025
577c421
corec: turn memheap macros to inline functions
robUx4 Jan 3, 2025
c496222
corec: turn memheap macros to inline functions
robUx4 Jan 3, 2025
192b678
corec: make MemHeap_Null() private to the array
robUx4 Jan 3, 2025
2ab509a
corec: use a special macro to get the cc_memheap
robUx4 Jan 3, 2025
da88e2f
corec: stronger typing of dataheaphead macros
robUx4 Jan 3, 2025
da883d1
corec: stronger typing of datahead macros
robUx4 Jan 3, 2025
8bdaa7c
corec: cast early to datahead
robUx4 Jan 3, 2025
7556bd8
corec: simplify access to dataheaphead
robUx4 Jan 3, 2025
ccd0f6b
corec: pass the array directly to Data_Clear()
robUx4 Jan 3, 2025
c081de1
corec: merge Data_Clear() and ArrayClear()
robUx4 Jan 3, 2025
06644bc
corec: pass the array directly to Data_ReAlloc()
robUx4 Jan 3, 2025
743532a
corec: simplify Data_ReAlloc()
robUx4 Jan 3, 2025
5358c19
corec: simplify datahead realloc code
robUx4 Jan 3, 2025
d474e0e
corec: only get datahead from an array
robUx4 Jan 3, 2025
3ac1437
corec: don't use Data_Head() on NULL arrays
robUx4 Jan 3, 2025
3002db6
corec: don't use a moving pointer in the FIFO
robUx4 Jan 3, 2025
cbab81a
corec: use void* for array pointers
robUx4 Jan 3, 2025
bc4394e
corec: cast internal node pointers using void*
robUx4 Jan 3, 2025
80859ca
corec: store the used size rather than the end pointer
robUx4 Jan 3, 2025
40b7862
corec: remove unused macro
robUx4 Jan 3, 2025
235c9bb
corec: only get dataheaphead from an array
robUx4 Jan 3, 2025
13026f4
corec: inline MemHeap_Null()
robUx4 Jan 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 129 additions & 101 deletions corec/corec/array/array.c

Large diffs are not rendered by default.

27 changes: 12 additions & 15 deletions corec/corec/array/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,24 @@ extern "C" {
#define ARRAY_DLL
#endif

#define Data_Var(type,name,len) struct { size_t n; type p[len]; } __##name; type* name = (__##name.n = sizeof(__##name.p),__##name.p)

typedef struct cc_memheap cc_memheap;

typedef struct array
{
// these are private members, use ARRAY macros to access them
uint8_t* _Begin;
uint8_t* _End;
void* _Begin;
size_t _Used;

} array;

typedef int (*arraycmp)(const void* Param, const void* a,const void* b);

#define ARRAY_AUTO_COUNT ((size_t)-1)

static INLINE void ArrayInit(array* p) { p->_Begin = NULL; p->_End = NULL; }
static INLINE void ArrayInit(array* p) { p->_Begin = NULL; p->_Used = 0; }
ARRAY_DLL void ArrayInitEx(array*,const cc_memheap*);
ARRAY_DLL void ArrayClear(array*);
ARRAY_DLL void ArrayDrop(array*);
ARRAY_DLL size_t ArraySize(const array*);
ARRAY_DLL bool_t ArrayEq(const array* a, const array* b);
ARRAY_DLL bool_t ArrayCopy(array*,const array* In);
ARRAY_DLL bool_t ArrayResize(array*,size_t Size,size_t Align);
Expand All @@ -65,14 +62,14 @@ ARRAY_DLL void ArrayDelete(array* p, size_t Ofs, size_t Length);

#ifdef CONFIG_DEBUGCHECKS
#define ARRAYBEGIN(Array,Type) (assert(&(Array)!=NULL),(Type*)((Array)._Begin))
#define ARRAYEND(Array,Type) (assert(&(Array)!=NULL),(Type*)((Array)._End))
#define ARRAYEMPTY(Array) (assert(&(Array)!=NULL),(Array)._Begin==(Array)._End)
#define ARRAYEMPTY(Array) (assert(&(Array)!=NULL),(Array)._Used==0)
#define ARRAYCOUNT(Array,Type) (assert(&(Array)!=NULL),(((Array)._Used))/sizeof(Type))
#else
#define ARRAYBEGIN(Array,Type) ((Type*)((Array)._Begin))
#define ARRAYEND(Array,Type) ((Type*)((Array)._End))
#define ARRAYEMPTY(Array) ((Array)._Begin==(Array)._End)
#define ARRAYEMPTY(Array) ((Array)._Used==0)
#define ARRAYCOUNT(Array,Type) ((((Array)._Used))/sizeof(Type))
#endif
#define ARRAYCOUNT(Array,Type) ((size_t)(((Array)._End)-((Array)._Begin))/sizeof(Type))
#define ARRAYEND(Array,Type) (ARRAYBEGIN(Array,Type) + ((((Array)._Used))/sizeof(Type)))

// TODO: move this to base/mem and depend on "mem" platform dependently(?)
typedef struct block
Expand All @@ -98,11 +95,11 @@ typedef struct cc_fifo
{
// private members
array _Base;
uint8_t* _Read;
size_t _Read;

} cc_fifo;

static INLINE void Fifo_Init(cc_fifo* p) { ArrayInit(&p->_Base); p->_Read = NULL; }
static INLINE void Fifo_Init(cc_fifo* p) { ArrayInit(&p->_Base); p->_Read = 0; }
ARRAY_DLL void Fifo_Clear(cc_fifo*);
ARRAY_DLL void Fifo_Drop(cc_fifo*);
ARRAY_DLL bool_t Fifo_Alloc(cc_fifo* p, size_t Size, size_t Align);
Expand All @@ -113,8 +110,8 @@ static INLINE void Fifo_Readed(cc_fifo* p, size_t Length)
p->_Read += Length;
}

#define FIFO_SIZE(p) (ARRAYEND((p)._Base,uint8_t)-(p)._Read)
#define FIFO_BEGIN(p) ((p)._Read)
#define FIFO_SIZE(p) (ARRAYCOUNT((p)._Base,uint8_t) - (p)._Read)
#define FIFO_BEGIN(p) (ARRAYBEGIN((p)._Base,uint8_t) + (p)._Read)
#define FIFO_END(p) ARRAYEND((p)._Base,uint8_t)

#ifdef __cplusplus
Expand Down
3 changes: 1 addition & 2 deletions corec/corec/helpers/parser/parser2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1137,8 +1137,7 @@ static dataid FindStrParam(node* p,const tchar_t* Token)
static void EnumStr(node *p,array* List)
{
dataid Id,*i;
size_t StrSize = ArraySize(&Parser_Context(p)->StrTab.Table);
StrSize /= STRTAB_ITEMSIZE;
size_t StrSize = StrTab_Size(&Parser_Context(p)->StrTab);

ArrayInit(List);
ArrayResize(List,StrSize*sizeof(dataid),0);
Expand Down
6 changes: 5 additions & 1 deletion corec/corec/helpers/parser/strtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ typedef struct stringdef

void StrTab_Init(strtab* p, const cc_memheap* Heap, size_t Alloc)
{
assert(STRTAB_ITEMSIZE == sizeof(stringdef));
p->Heap = Heap;
ArrayInit(&p->Table); // not using Heap, because we need direct write acess
ArrayAlloc(&p->Table,Alloc,TABLEALIGN);
Expand All @@ -35,6 +34,11 @@ static NOINLINE void StrTab_Clear(strtab* p)
ArrayClear(&p->Table);
}

size_t StrTab_Size(const strtab* p)
{
return ARRAYCOUNT(p->Table, stringdef);
}

void StrTab_Done(strtab* p)
{
StrTab_Clear(p);
Expand Down
2 changes: 1 addition & 1 deletion corec/corec/helpers/parser/strtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@


#define STRTAB_INVALID_POS ((size_t)-1)
#define STRTAB_ITEMSIZE 8

void StrTab_Init(strtab*, const cc_memheap* Heap, size_t Alloc);
void StrTab_Done(strtab*);
size_t StrTab_Size(const strtab*);
const tchar_t* StrTab_Find(strtab*, fourcc_t Class, int Id);
size_t StrTab_Pos(strtab*, fourcc_t Class, int Id);
const tchar_t* StrTab_GetPos(strtab*, size_t Pos);
Expand Down
26 changes: 18 additions & 8 deletions corec/corec/memheap.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ typedef void (*memheap_free)(const void* This,void*,size_t);
typedef void* (*memheap_realloc)(const void* This,void*,size_t Old,size_t New);
typedef void (*memheap_write)(const void* This,void*,const void* Src,size_t Pos,size_t Size);

#define DATA_FLAG_HEAP (((size_t)1)<<(sizeof(size_t)*8-1))
#define DATA_FLAG_MEMHEAP (((size_t)1)<<(sizeof(size_t)*8-2))

typedef struct dataheaphead
{
const cc_memheap* Heap;
Expand All @@ -36,10 +33,23 @@ struct cc_memheap
dataheaphead Null;
};

#define MemHeap_Alloc(p,a,b) ((cc_memheap*)(p))->Alloc(p,a,b)
#define MemHeap_Free(p,a,b) ((cc_memheap*)(p))->Free(p,a,b)
#define MemHeap_ReAlloc(p,a,b,c) ((cc_memheap*)(p))->ReAlloc(p,a,b,c)
#define MemHeap_Write(p,a,b,c,d) ((cc_memheap*)(p))->Write(p,a,b,c,d)
#define MemHeap_Null(p) ((uint8_t*)(&((cc_memheap*)(p))->Null+1))
extern const cc_memheap *MemHeap_Default;

static INLINE void *MemHeap_Alloc(const cc_memheap *p, size_t s, int Flags)
{
return p->Alloc(p, s, Flags);
}
static INLINE void MemHeap_Free(const cc_memheap *p, void *ptr, size_t s)
{
p->Free(p, ptr, s);
}
static INLINE void *MemHeap_ReAlloc(const cc_memheap *p, void *ptr, size_t old, size_t new)
{
return p->ReAlloc(p, ptr, old, new);
}
static INLINE void MemHeap_Write(const cc_memheap *p, void *ptr, void *src, size_t pos, size_t size)
{
p->Write(p, ptr, src, pos, size);
}

#endif
24 changes: 9 additions & 15 deletions corec/corec/node/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ static NOINLINE bool_t CallDelete(nodecontext* p,node* Node,const nodeclass* Cla
else
if (m->Meta == (META_MODE_DATA | TYPE_ARRAY) && (intptr_t)m->Data>=0)
{
array* Ptr = (array*)((uint8_t*)Node+m->Data);
array* Ptr = (void*)((uint8_t*)Node+m->Data);
#if defined(CONFIG_CORECDOC)
if (m[2].Meta == META_PARAM_DATA_FLAGS)
{
Expand All @@ -675,7 +675,7 @@ static NOINLINE bool_t CallDelete(nodecontext* p,node* Node,const nodeclass* Cla
else
if (m->Meta == (META_MODE_DATA | TYPE_NODE_REF) && (intptr_t)m->Data>=0)
{
node** Ptr = (node**)((uint8_t*)Node+m->Data);
node** Ptr = (void*)((uint8_t*)Node+m->Data);
node* v = *Ptr;
if (v)
{
Expand Down Expand Up @@ -769,7 +769,7 @@ static void MetaConst(const nodemeta* i,void* Data)
{
size_t Size = ParamSize[i->Meta & TYPE_MASK];
if (Size == sizeof(uintptr_t))
*(uintptr_t*)((uint8_t*)Data+i->Id) = i->Data;
memcpy((uint8_t*)Data+i->Id,&i->Data,sizeof(uintptr_t));
else
{
memset((uint8_t*)Data+i->Id,0,Size);
Expand Down Expand Up @@ -798,7 +798,7 @@ static err_t CallCreate(nodecontext* p,node* Node,const nodeclass* Class)
else
if (i->Meta == (META_MODE_DATA | TYPE_ARRAY) && (intptr_t)i->Data>=0)
{
array* Ptr = (array*)((uint8_t*)Node+i->Data);
array* Ptr = (void*)((uint8_t*)Node+i->Data);
ArrayInitEx(Ptr,p->NodeHeap);
}
else
Expand Down Expand Up @@ -2060,7 +2060,7 @@ static err_t MetaGet(node* p,dataid Id,void* Data,size_t Size)
else
{
const nodemeta* m = Lookup[Mid].Meta;
const uint8_t* Ptr;
const void* Ptr;
datatype Type;

if (m->Meta == META_PARAM_GET)
Expand Down Expand Up @@ -2224,7 +2224,7 @@ static err_t MetaSet(node* p,dataid Id,const void* Data,size_t Size)
else
{
uint32_t Bit;
uint8_t* Ptr = (uint8_t*)p + (intptr_t)MetaData;
void* Ptr = (uint8_t*)p + (intptr_t)MetaData;
size_t DataSize = Node_MaxDataSize(p,Id,Type,META_PARAM_SET);

assert((Type & TYPE_MASK) == TYPE_STRING || !Data || Size == DataSize);
Expand Down Expand Up @@ -2433,7 +2433,7 @@ static err_t MetaUnSet(node* p,dataid Id,const void* Data,size_t Size)
else
{
uint32_t Bit;
uint8_t* Ptr = (uint8_t*)p + (intptr_t)MetaData;
void* Ptr = (uint8_t*)p + (intptr_t)MetaData;
size_t DataSize = Node_MaxDataSize(p,Id,Type,META_PARAM_UNSET);

assert((Type & TYPE_MASK) == TYPE_STRING || !Data || Size == DataSize);
Expand Down Expand Up @@ -2595,12 +2595,6 @@ META_PARAM(TYPE,NODECONTEXT_PROJECT_BUILD,TYPE_INT|TFLAG_SETUP|TFLAG_RDONLY)
META_DATA(TYPE_INT,NODECONTEXT_PROJECT_BUILD,nodecontext,Build)
META_END(NODEMODULE_CLASS)

static void* __HAlloc(const void* UNUSED_PARAM(p),size_t Size,int UNUSED_PARAM(Flags)) { return malloc(Size); }\
static void __HFree(const void* UNUSED_PARAM(p),void* Ptr,size_t UNUSED_PARAM(Size)) { free(Ptr); }\
static void* __HReAlloc(const void* UNUSED_PARAM(p),void* Ptr,size_t UNUSED_PARAM(OldSize),size_t Size) { return realloc(Ptr,Size); }\
static void __HWrite(const void* UNUSED_PARAM(p),void* Ptr,const void* Src,size_t Pos,size_t Size) { memcpy((uint8_t*)Ptr+Pos,Src,Size); }\
static const cc_memheap MemHeap_Default = { __HAlloc,__HFree,__HReAlloc,__HWrite,{ &MemHeap_Default, DATA_FLAG_MEMHEAP } };


void NodeContext_Init(nodecontext* p,const nodemeta* Custom, const cc_memheap* Heap, const cc_memheap* ConstHeap)
{
Expand All @@ -2616,7 +2610,7 @@ void NodeContext_Init(nodecontext* p,const nodemeta* Custom, const cc_memheap* H
ArrayInitEx(&p->NodeClass,Heap);
}
else
Heap = &MemHeap_Default;
Heap = MemHeap_Default;

if (!ConstHeap)
ConstHeap=Heap;
Expand Down Expand Up @@ -2742,7 +2736,7 @@ NOINLINE void NodeDup_Replace(array* Dup, node** Ptr)
}
}

static NOINLINE void CopyData(const nodeclass* Class, node* p, node* Src, array* Dup, uint8_t* Data)
static NOINLINE void CopyData(const nodeclass* Class, node* p, node* Src, array* Dup, void* Data)
{
if (Class->ParentClass)
CopyData(Class->ParentClass,p,Src,Dup,Data);
Expand Down
20 changes: 12 additions & 8 deletions libebml2/ebmlcrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ META_VMT(TYPE_FUNC,ebml_element_vmt,RenderData,RenderData)
#endif
META_END(EBML_ELEMENT_CLASS)

bool_t EBML_CRCMatches(ebml_crc *CRC, const uint8_t *Buf, size_t Size)
bool_t EBML_CRCMatches(ebml_crc *CRC, const void *Buf, size_t Size)
{
uint32_t testCRC = CRC32_NEGL;

Expand All @@ -217,40 +217,44 @@ bool_t EBML_CRCMatches(ebml_crc *CRC, const uint8_t *Buf, size_t Size)
for(; !aligned(Buf) && Size > 0; Size--)
testCRC = m_tab[CRC32_INDEX(testCRC) ^ *Buf++] ^ CRC32_SHIFTED(testCRC);
*/
const uint32_t *Buf32 = Buf;
while (Size >= 4)
{
testCRC ^= *(const uint32_t *)Buf;
testCRC ^= *Buf32;
testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
Size -= 4;
Buf += 4;
Buf32++;
}

const uint8_t *Buf8 = (const uint8_t *)Buf32;
while (Size--)
testCRC = m_tab[CRC32_INDEX(testCRC) ^ *Buf++] ^ CRC32_SHIFTED(testCRC);
testCRC = m_tab[CRC32_INDEX(testCRC) ^ *Buf8++] ^ CRC32_SHIFTED(testCRC);

testCRC ^= CRC32_NEGL;

return (CRC->CRC == testCRC);
}

void EBML_CRCAddBuffer(ebml_crc *CRC, const uint8_t *Buf, size_t Size)
void EBML_CRCAddBuffer(ebml_crc *CRC, const void *Buf, size_t Size)
{
const uint32_t *Buf32 = Buf;
while (Size >= 4)
{
CRC->CRC ^= *(const uint32_t *)Buf;
CRC->CRC ^= *Buf32;
CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
Size -= 4;
Buf += 4;
Buf32++;
}

const uint8_t *Buf8 = (const uint8_t *)Buf32;
while (Size--)
CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC) ^ *Buf++] ^ CRC32_SHIFTED(CRC->CRC);
CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC) ^ *Buf8++] ^ CRC32_SHIFTED(CRC->CRC);
}

void EBML_CRCFinalize(ebml_crc *CRC)
Expand Down
4 changes: 2 additions & 2 deletions libebml2/ebmlcrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#ifndef __LIBEBML_CRC_H
#define __LIBEBML_CRC_H

extern bool_t EBML_CRCMatches(ebml_crc *CRC, const uint8_t *Buf, size_t Size);
extern void EBML_CRCAddBuffer(ebml_crc *CRC, const uint8_t *Buf, size_t Size);
extern bool_t EBML_CRCMatches(ebml_crc *CRC, const void *Buf, size_t Size);
extern void EBML_CRCAddBuffer(ebml_crc *CRC, const void *Buf, size_t Size);
extern void EBML_CRCFinalize(ebml_crc *CRC);

#endif /* __LIBEBML_CRC_H */
4 changes: 3 additions & 1 deletion libebml2/ebmlmaster.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ static err_t ReadData(ebml_master *Element, struct stream *Input, const ebml_par
{
if (EBML_ElementIsFiniteSize((ebml_element*)Element))
{
CRCElement = (ebml_crc*)SubElement;
if (Node_IsPartOf(Input, MEMSTREAM_CLASS))
{
filepos_t DataPos = Stream_Seek(Input,EBML_ElementPositionEnd(SubElement),SEEK_SET);
Expand Down Expand Up @@ -354,11 +355,12 @@ static err_t ReadData(ebml_master *Element, struct stream *Input, const ebml_par
StreamClose(ReadStream);
ReadStream=Input; // revert back to normal reading
ArrayClear(&CrcBuffer);
CRCData = NULL;
CRCElement = NULL;
}
}
}
}
CRCElement = (ebml_crc*)SubElement;
}
bFirst = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion libmatroska2/matroskablock.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ err_t MATROSKA_BlockProcessFrameDurations(matroska_block *Block, struct stream *
{
EBML_StringGet((ebml_string*)Elt,CodecID,TSIZEOF(CodecID));
ReadData = 0;
if (!ArraySize(&Block->Data))
if (!ARRAYCOUNT(Block->Data,uint8_t))
{
Err = MATROSKA_BlockReadData(Block,Input,ForProfile);
if (Err!=ERR_NONE)
Expand Down
Loading