CVE-2023-4681: NULL Pointer Dereference (CWE-476)
value: NULL Pointer Dereference in GitHub repository gpac/gpac prior to 2.3-DEV.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2023-08-31T16:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/filters/dasher.c, src/media_tools/avilib.c, src/media_tools/mpeg2_ps.c
Commit date: 2023-08-31 16:44:06 +0200
Commit message: fixed #2575

Diff: diff --git a/src/filters/dasher.c b/src/filters/dasher.c
index 2619d2291c..bc768804fd 100644
--- a/src/filters/dasher.c
+++ b/src/filters/dasher.c
@@ -8385,10 +8385,13 @@ static GF_Err dasher_process(GF_Filter *filter)
 	if (!ctx->min_cts_period.den) {
 		u64 min_ts=0, min_timescale = 0;
 		u32 num_ready=0, num_blocked=0;
 		for (i=0; i<count; i++) {
 			GF_DashStream *ds = gf_list_get(ctx->current_period->streams, i);
+			if (ctx->force_period_switch) {
+				break;
+			}
 			GF_FilterPacket *pck = gf_filter_pid_get_packet(ds->ipid);
 			if (!pck) continue;
 			u64 ts = gf_filter_pck_get_cts(pck);
 			//only adjust if delay is negative (skip), otherwise (delay) keep mints as is.
 			//Not doing so will set the rep PTO to the delay, canceling the delay ...
@@ -8404,10 +8407,13 @@ static GF_Err dasher_process(GF_Filter *filter)
 		if (count) {
 			if (num_ready < num_blocked) return GF_OK;
 		}
 		ctx->min_cts_period.num = min_ts;
 		ctx->min_cts_period.den = min_timescale;
+
+		if (ctx->force_period_switch)
+			count = gf_list_count(ctx->current_period->streams);
 	}
 
 	nb_init = has_init = nb_reg_done = 0;
 
 	for (i=0; i<count; i++) {
diff --git a/src/media_tools/avilib.c b/src/media_tools/avilib.c
index 27cd81133d..be93bc3a78 100644
--- a/src/media_tools/avilib.c
+++ b/src/media_tools/avilib.c
@@ -1946,12 +1946,15 @@ int avi_parse_input_file(avi_t *AVI, int getIndex)
 
 				// offset of header
 
 				header_offset = gf_ftell(AVI->fdes);
 
-				if( avi_read(AVI->fdes,(char *)hdrl_data, (u32) n) != n ) ERR_EXIT(AVI_ERR_READ)
+				if( avi_read(AVI->fdes,(char *)hdrl_data, (u32) n) != n ) {
+					if (hdrl_data) gf_free(hdrl_data);
+					ERR_EXIT(AVI_ERR_READ)
 				}
+			}
 			else if(strnicmp(data,"movi",4) == 0)
 			{
 				AVI->movi_start = gf_ftell(AVI->fdes);
 				if (gf_fseek(AVI->fdes,n,SEEK_CUR)==(u64)-1) break;
 			}
@@ -1962,23 +1965,28 @@ int avi_parse_input_file(avi_t *AVI, int getIndex)
 			/* n must be a multiple of 16, but the reading does not
 			   break if this is not the case */
 
 			AVI->n_idx = AVI->max_idx = (u32) (n/16);
 			AVI->idx = (unsigned  char((*)[16]) ) gf_malloc((u32)n);
-			if(AVI->idx==0) ERR_EXIT(AVI_ERR_NO_MEM)
-				if(avi_read(AVI->fdes, (char *) AVI->idx, (u32) n) != n ) {
-					gf_free( AVI->idx);
-					AVI->idx=NULL;
-					AVI->n_idx = 0;
-				}
+			if(AVI->idx==0) {
+				if (hdrl_data) gf_free(hdrl_data);
+				ERR_EXIT(AVI_ERR_NO_MEM)
+			}
+			if(avi_read(AVI->fdes, (char *) AVI->idx, (u32) n) != n ) {
+				gf_free( AVI->idx);
+				AVI->idx=NULL;
+				AVI->n_idx = 0;
+				if (hdrl_data) gf_free(hdrl_data);
+				ERR_EXIT(AVI_ERR_READ)
+			}
 		}
 		else
 			gf_fseek(AVI->fdes,n,SEEK_CUR);
 	}
 
-	if(!hdrl_data      ) ERR_EXIT(AVI_ERR_NO_HDRL)
-		if(!AVI->movi_start) ERR_EXIT(AVI_ERR_NO_MOVI)
+	if(!hdrl_data) ERR_EXIT(AVI_ERR_NO_HDRL)
+	if(!AVI->movi_start) ERR_EXIT(AVI_ERR_NO_MOVI)
 
 			/* Interpret the header list */
 
 			for(i=0; i<hdrl_len;)
 			{
diff --git a/src/media_tools/mpeg2_ps.c b/src/media_tools/mpeg2_ps.c
index 8e33e48d40..0af7a31f32 100644
--- a/src/media_tools/mpeg2_ps.c
+++ b/src/media_tools/mpeg2_ps.c
@@ -994,10 +994,11 @@ static void get_info_from_frame (mpeg2ps_stream_t *sptr,
 		                       &sptr->frame_rate,
 		                       &sptr->bit_rate,
 		                       &sptr->par) < 0) {
 			sptr->m_stream_id = 0;
 			sptr->m_fd = FDNULL;
+			return;
 		}
 		sptr->ticks_per_frame = (u64)(90000.0 / sptr->frame_rate);
 		return;
 	}
 
@@ -1200,11 +1201,11 @@ static void get_info_for_all_streams (mpeg2ps_t *ps)
 				sptr->m_fd = FDNULL;
 				continue;
 			}
 			get_info_from_frame(sptr, buffer, buflen);
 			// here - if (sptr->first_pes_has_dts == 0) should be processed
-			if (sptr->first_pes_has_dts == 0) {
+			if ((sptr->first_pes_has_dts == 0) && sptr->m_fd) {
 				u32 frames_from_beg = 0;
 				Bool have_frame;
 				do {
 					advance_frame(sptr);
 					have_frame =

Vulnerable code: 				if( avi_read(AVI->fdes,(char *)hdrl_data, (u32) n) != n ) ERR_EXIT(AVI_ERR_READ)
			if(AVI->idx==0) ERR_EXIT(AVI_ERR_NO_MEM)
				if(avi_read(AVI->fdes, (char *) AVI->idx, (u32) n) != n ) {
					gf_free( AVI->idx);
					AVI->idx=NULL;
					AVI->n_idx = 0;
				}
	if(!hdrl_data      ) ERR_EXIT(AVI_ERR_NO_HDRL)
		if(!AVI->movi_start) ERR_EXIT(AVI_ERR_NO_MOVI)
			if (sptr->first_pes_has_dts == 0) {
Fixed code: 			if (ctx->force_period_switch) {
				break;
			}

		if (ctx->force_period_switch)
			count = gf_list_count(ctx->current_period->streams);
				if( avi_read(AVI->fdes,(char *)hdrl_data, (u32) n) != n ) {
					if (hdrl_data) gf_free(hdrl_data);
					ERR_EXIT(AVI_ERR_READ)
			}
			if(AVI->idx==0) {
				if (hdrl_data) gf_free(hdrl_data);
				ERR_EXIT(AVI_ERR_NO_MEM)
			}
			if(avi_read(AVI->fdes, (char *) AVI->idx, (u32) n) != n ) {
				gf_free( AVI->idx);
				AVI->idx=NULL;
				AVI->n_idx = 0;
				if (hdrl_data) gf_free(hdrl_data);
				ERR_EXIT(AVI_ERR_READ)
			}
	if(!hdrl_data) ERR_EXIT(AVI_ERR_NO_HDRL)
	if(!AVI->movi_start) ERR_EXIT(AVI_ERR_NO_MOVI)
			return;
			if ((sptr->first_pes_has_dts == 0) && sptr->m_fd) {