https://gitlab.xiph.org/xiph/ogg/-/commit/7cf42ea17aef7bc1b7b21af70724840a96c2e7d0 From 7cf42ea17aef7bc1b7b21af70724840a96c2e7d0 Mon Sep 17 00:00:00 2001 From: "Timothy B. Terriberry" Date: Tue, 11 Jun 2024 03:54:24 -0700 Subject: [PATCH] Fix UB reported by UBsan. Also fix other instances of similar patterns. Thanks to kunitoki for the report. Fixes #2305 --- a/src/bitwise.c +++ b/src/bitwise.c @@ -284,13 +284,13 @@ long oggpack_look(oggpack_buffer *b,int bits){ ret=b->ptr[0]>>b->endbit; if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); + ret|=(unsigned long)b->ptr[1]<<(8-b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); + ret|=(unsigned long)b->ptr[2]<<(16-b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); + ret|=(unsigned long)b->ptr[3]<<(24-b->endbit); if(bits>32 && b->endbit) - ret|=b->ptr[4]<<(32-b->endbit); + ret|=(unsigned long)b->ptr[4]<<(32-b->endbit); } } } @@ -313,13 +313,13 @@ long oggpackB_look(oggpack_buffer *b,int bits){ else if(!bits)return(0L); } - ret=b->ptr[0]<<(24+b->endbit); + ret=(unsigned long)b->ptr[0]<<(24+b->endbit); if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); + ret|=(unsigned long)b->ptr[1]<<(16+b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); + ret|=(unsigned long)b->ptr[2]<<(8+b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); + ret|=(unsigned long)b->ptr[3]<<(b->endbit); if(bits>32 && b->endbit) ret|=b->ptr[4]>>(8-b->endbit); } @@ -389,13 +389,13 @@ long oggpack_read(oggpack_buffer *b,int bits){ ret=b->ptr[0]>>b->endbit; if(bits>8){ - ret|=b->ptr[1]<<(8-b->endbit); + ret|=(unsigned long)b->ptr[1]<<(8-b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(16-b->endbit); + ret|=(unsigned long)b->ptr[2]<<(16-b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(24-b->endbit); + ret|=(unsigned long)b->ptr[3]<<(24-b->endbit); if(bits>32 && b->endbit){ - ret|=b->ptr[4]<<(32-b->endbit); + ret|=(unsigned long)b->ptr[4]<<(32-b->endbit); } } } @@ -430,13 +430,13 @@ long oggpackB_read(oggpack_buffer *b,int bits){ else if(!bits)return(0L); } - ret=b->ptr[0]<<(24+b->endbit); + ret=(unsigned long)b->ptr[0]<<(24+b->endbit); if(bits>8){ - ret|=b->ptr[1]<<(16+b->endbit); + ret|=(unsigned long)b->ptr[1]<<(16+b->endbit); if(bits>16){ - ret|=b->ptr[2]<<(8+b->endbit); + ret|=(unsigned long)b->ptr[2]<<(8+b->endbit); if(bits>24){ - ret|=b->ptr[3]<<(b->endbit); + ret|=(unsigned long)b->ptr[3]<<(b->endbit); if(bits>32 && b->endbit) ret|=b->ptr[4]>>(8-b->endbit); } --- a/src/framing.c +++ b/src/framing.c @@ -349,12 +349,13 @@ int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){ int i; int vals=0; - int maxvals=(os->lacing_fill>255?255:os->lacing_fill); + int maxvals; int bytes=0; long acc=0; ogg_int64_t granule_pos=-1; if(ogg_stream_check(os)) return(0); + maxvals=(os->lacing_fill>255?255:os->lacing_fill); if(maxvals==0) return(0); /* construct a page */ @@ -639,12 +640,15 @@ int ogg_sync_wrote(ogg_sync_state *oy, long bytes){ */ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){ - unsigned char *page=oy->data+oy->returned; + unsigned char *page; unsigned char *next; - long bytes=oy->fill-oy->returned; + long bytes; if(ogg_sync_check(oy))return 0; + page=oy->data+oy->returned; + bytes=oy->fill-oy->returned; + if(oy->headerbytes==0){ int headerbytes,i; if(bytes<27)return(0); /* not enough for a header */ @@ -1086,11 +1090,11 @@ void print_header(ogg_page *og){ (int)og->header[4],(int)og->header[5]); fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n", - (og->header[9]<<24)|(og->header[8]<<16)| + ((unsigned)og->header[9]<<24)|(og->header[8]<<16)| (og->header[7]<<8)|og->header[6], - (og->header[17]<<24)|(og->header[16]<<16)| + ((unsigned)og->header[17]<<24)|(og->header[16]<<16)| (og->header[15]<<8)|og->header[14], - ((long)(og->header[21])<<24)|(og->header[20]<<16)| + ((long)((unsigned)og->header[21])<<24)|(og->header[20]<<16)| (og->header[19]<<8)|og->header[18]); fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (", -- GitLab