CVE-2023-5595: Insufficient Information (NVD-CWE-noinfo)
value: Denial of Service in GitHub repository gpac/gpac prior to 2.3.0-DEV.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 5.5
Published: 2023-10-16T09:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/filters/isoffin_load.c, src/filters/mux_isom.c, src/isomedia/media.c, src/isomedia/tx3g.c
Commit date: 2023-10-13 12:21:25 +0200
Commit message: fixes #2633 - 3 segv + memleak

Diff: diff --git a/src/filters/isoffin_load.c b/src/filters/isoffin_load.c
index 8a56b593f41..1304e899a00 100644
--- a/src/filters/isoffin_load.c
+++ b/src/filters/isoffin_load.c
@@ -87,11 +87,11 @@ static void isor_get_chapters(GF_ISOFile *file, GF_FilterPid *opid)
 		if (!s) continue;
 		GF_BitStream *bs = gf_bs_new(s->data, s->dataLength, GF_BITSTREAM_READ);
 		GF_TextSample *txt = gf_isom_parse_text_sample(bs);
 		if (txt) {
 			times.vals[i] = (u32) s->DTS;
-			names.vals[i] = gf_strdup(txt->text);
+			names.vals[i] = gf_strdup(txt->text ? txt->text : "");
 			gf_isom_delete_text_sample(txt);
 		}
 		gf_bs_del(bs);
 		gf_isom_sample_del(&s);
 	}
@@ -1103,11 +1103,11 @@ props_done:
 
 	if (lang_desc) {
 		gf_odf_desc_del((GF_Descriptor *)lang_desc);
 		lang_desc = NULL;
 	}
-	
+
 	if (read->smode != MP4DMX_SINGLE) {
 		if ((codec_id==GF_CODECID_LHVC) || (codec_id==GF_CODECID_HEVC)) {
 			Bool signal_lhv = (read->smode==MP4DMX_SPLIT) ? GF_TRUE : GF_FALSE;
 			GF_HEVCConfig *hvcc = gf_isom_hevc_config_get(read->mov, track, stsd_idx);
 			GF_HEVCConfig *lhcc = gf_isom_lhvc_config_get(read->mov, track, stsd_idx);
@@ -1748,11 +1748,11 @@ GF_Err isor_declare_objects(ISOMReader *read)
 	}
 	if (! gf_list_count(read->channels)) {
 		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[IsoMedia] No suitable tracks in file\n"));
 		return GF_NOT_SUPPORTED;
 	}
-	
+
 	/*if cover art, declare a video pid*/
 	if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_COVER_ART, &tag, &tlen)==GF_OK) {
 
 		/*write cover data*/
 		assert(!(tlen & 0x80000000));
@@ -1851,11 +1851,11 @@ retry:
 		gf_filter_pid_set_property(pid, GF_PROP_PID_ID, &PROP_UINT(esd ? esd->ESID : item_id));
 	}
 
 	if (read->itemid)
 		gf_filter_pid_set_property(pid, GF_PROP_PID_ITEM_ID, &PROP_UINT(item_id));
-		
+
 	if ((item_codecid==GF_CODECID_HEVC) && gf_isom_meta_item_has_ref(read->mov, GF_TRUE, 0, item_id, GF_ISOM_REF_TBAS)) {
 		gf_filter_pid_set_property(pid, GF_PROP_PID_TILE_BASE, &PROP_BOOL(GF_TRUE));
 	}
 
 
@@ -1946,8 +1946,5 @@ retry:
 	}
 	return GF_TRUE;
 }
 
 #endif // !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_MP4DMX)
-
-
-
diff --git a/src/filters/mux_isom.c b/src/filters/mux_isom.c
index 57e9e7834ce..29bdbb64b84 100644
--- a/src/filters/mux_isom.c
+++ b/src/filters/mux_isom.c
@@ -1025,11 +1025,11 @@ static GF_Err mp4_mux_setup_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_tr
 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, NULL);
 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_UNFRAMED, NULL);
 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(GF_STREAM_FILE) );
 
 		mux_assign_mime_file_ext(pid, ctx->opid, ISOM_FILE_EXT, ISOM_FILE_MIME, NULL);
-		
+
 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DASH_MODE, NULL);
 		//we dispatch timing in milliseconds
 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_TIMESCALE, &PROP_UINT(1000));
 
 		switch (ctx->store) {
@@ -1078,11 +1078,11 @@ static GF_Err mp4_mux_setup_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_tr
 	tkw = gf_filter_pid_get_udta(pid);
 	if (!tkw) {
 		GF_FilterEvent evt;
 		GF_SAFEALLOC(tkw, TrackWriter);
 		if (!tkw) return GF_OUT_OF_MEM;
-		
+
 		gf_list_add(ctx->tracks, tkw);
 		tkw->ipid = pid;
 		tkw->fake_track = !is_true_pid;
 		tkw->min_cts = (u64) -1;
 
@@ -2613,11 +2613,11 @@ sample_entry_setup:
 			if (e) {
 				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MP4Mux] Error creating new AVC sample description: %s\n", gf_error_to_string(e) ));
 				return e;
 			}
 		}
-		
+
 		if (xps_inband) {
 			//this will cleanup all PS in avcC / svcC
 			gf_isom_avc_set_inband_config(ctx->file, tkw->track_num, tkw->stsd_idx, (xps_inband==XPS_IB_BOTH) ? GF_TRUE : GF_FALSE);
 			if (xps_inband==XPS_IB_BOTH) make_inband_headers = GF_TRUE;
 		} else {
@@ -3211,11 +3211,11 @@ sample_entry_setup:
 				udesc.ext_box_wrap = GF_4CC('G', 'M', 'C', 'C');
 			} else {
 				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MP4Mux] muxing unknown codec ID %s, using generic sample entry with 4CC \"%s\"\n", gf_codecid_name(codec_id), gf_4cc_to_str(m_subtype) ));
 			}
 		}
-		
+
 		e = gf_isom_new_generic_sample_description(ctx->file, tkw->track_num, (char *)src_url, NULL, &udesc, &tkw->stsd_idx);
 		if (gpac_meta_dsi) gf_free(gpac_meta_dsi);
 
 		if (e) {
 			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MP4Mux] Error creating new sample description for stream type %d codecid %d: %s\n", tkw->stream_type, codec_id, gf_error_to_string(e) ));
@@ -3760,11 +3760,11 @@ sample_entry_done:
 						break;
 
 					if (add_chap) {
 						gf_isom_add_chapter(ctx->file, 0, start_time, p2->value.string_list.vals[j]);
 					}
-					if (add_tk) {
+					if (add_tk && p2->value.string_list.vals[j]) {
 						GF_TextSample tx;
 						memset(&tx, 0, sizeof(tx));
 						tx.text = p2->value.string_list.vals[j];
 						tx.len = (u32) strlen(p2->value.string_list.vals[j])+1;
 						GF_ISOSample *samp = gf_isom_text_to_sample(&tx);
@@ -4361,11 +4361,11 @@ static GF_Err mp4_mux_cenc_update(GF_MP4MuxCtx *ctx, TrackWriter *tkw, GF_Filter
 			e = gf_isom_set_sample_cenc_group(ctx->file, tkw->track_num, sample_num, GF_FALSE, 0, 0, dumb_key, 20);
 			IV_size = 0;
 			tkw->has_seig = GF_TRUE;
 		}
 	} else {
-	
+
 		e = GF_OK;
 		//multikey ALWAYS uses seig
 		if (tkw->cenc_ki->value.data.ptr[0])
 			needs_seig = GF_TRUE;
 		else if (tkw->def_crypt_byte_block != tkw->crypt_byte_block)
@@ -5012,11 +5012,11 @@ static GF_Err mp4_mux_process_sample(GF_MP4MuxCtx *ctx, TrackWriter *tkw, GF_Fil
 			}
 			if (sap_type && !tkw->gdr_type)
 				tkw->gdr_type = sap_type;
 		}
 	}
-	
+
 	subs = gf_filter_pck_get_property(pck, GF_PROP_PCK_SUBS);
 	if (subs) {
 		//if no AUDelim nal and inband header injection, push new subsample
 		if (!first_nal_is_audelim && insert_subsample_dsi_size) {
 			if (for_fragment) {
@@ -7105,11 +7105,11 @@ retry_pck:
 
 	if (not_ready) {
 		if (blocking_refs && has_ready) {
 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MP4Mux] Blocking input packets present, aborting initial timing sync\n"));
 		}
-		//this may be quite long until we have a packet in case input pid is video encoding 
+		//this may be quite long until we have a packet in case input pid is video encoding
 		else if (ctx->config_retry_start && (gf_sys_clock() - ctx->config_retry_start > 10000)) {
 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MP4Mux] No input packets present on one or more inputs for more than 10s, aborting initial timing sync\n"));
 		} else {
 			ctx->config_retry_start = gf_sys_clock();
 			del_service_info(services);
@@ -7906,11 +7906,11 @@ static GF_Err mp4_mux_done(GF_MP4MuxCtx *ctx, Bool is_final)
 			GF_Err gf_isom_force_ctts(GF_ISOFile *file, u32 track);
 			gf_isom_force_ctts(ctx->file, tkw->track_num);
 		}
 
 		gf_isom_purge_track_reference(ctx->file, tkw->track_num);
-		
+
 		if (ctx->importer && ctx->dur.num && ctx->dur.den) {
 			u64 mdur = gf_isom_get_media_duration(ctx->file, tkw->track_num);
 			u64 pdur = gf_isom_get_track_duration(ctx->file, tkw->track_num);
 			if (pdur==mdur) {
 				GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[MP4Mux] Imported %d frames - duration %g\n", tkw->nb_samples, ((Double)mdur)/tkw->tk_timescale ));
@@ -8390,6 +8390,5 @@ const GF_FilterRegister *mp4mx_register(GF_FilterSession *session)
 const GF_FilterRegister *mp4mx_register(GF_FilterSession *session)
 {
 	return NULL;
 }
 #endif // GPAC_DISABLE_ISOM_WRITE
-
diff --git a/src/isomedia/media.c b/src/isomedia/media.c
index 2a2d6140f06..5c1941ae784 100644
--- a/src/isomedia/media.c
+++ b/src/isomedia/media.c
@@ -390,10 +390,12 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo
 			return GF_ISOM_INVALID_MEDIA;
 		if (true_desc_only) {
 			return GF_ISOM_INVALID_MEDIA;
 		} else {
 			GF_LASeRSampleEntryBox*ptr = (GF_LASeRSampleEntryBox*)entry;
+			if (!ptr || !ptr->lsr_config || !ptr->lsr_config->hdr_size)
+				return GF_ISOM_INVALID_MEDIA;
 			esd =  gf_odf_desc_esd_new(2);
 			*out_esd = esd;
 			esd->decoderConfig->streamType = GF_STREAM_SCENE;
 			esd->decoderConfig->objectTypeIndication = GF_CODECID_LASER;
 			esd->decoderConfig->decoderSpecificInfo->dataLength = ptr->lsr_config->hdr_size;
@@ -1069,11 +1071,11 @@ GF_Err Media_AddSample(GF_MediaBox *mdia, u64 data_offset, const GF_ISOSample *s
 	if (!mdia->mediaTrack->chunk_cache) {
 		//and update the chunks
 		e = stbl_AddChunkOffset(mdia, sampleNumber, StreamDescIndex, data_offset, sample->nb_pack);
 		if (e) return e;
 	}
-	
+
 	if (!syncShadowNumber) return GF_OK;
 	if (!stbl->ShadowSync) {
 		stbl->ShadowSync = (GF_ShadowSyncBox *) gf_isom_box_new_parent(&stbl->child_boxes, GF_ISOM_BOX_TYPE_STSH);
 		if (!stbl->ShadowSync) return GF_OUT_OF_MEM;
 	}
diff --git a/src/isomedia/tx3g.c b/src/isomedia/tx3g.c
index 5891277ad4d..dab220d228e 100644
--- a/src/isomedia/tx3g.c
+++ b/src/isomedia/tx3g.c
@@ -100,16 +100,18 @@ GF_Err gf_isom_get_text_description(GF_ISOFile *movie, u32 trackNumber, u32 desc
 		(*out_desc)->default_pos = txt->default_box;
 		(*out_desc)->default_style = txt->default_style;
 		(*out_desc)->displayFlags = txt->displayFlags;
 		(*out_desc)->vert_justif = txt->vertical_justification;
 		(*out_desc)->horiz_justif = txt->horizontal_justification;
-		(*out_desc)->font_count = txt->font_table->entry_count;
-		(*out_desc)->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord) * txt->font_table->entry_count);
-		for (i=0; i<txt->font_table->entry_count; i++) {
-			(*out_desc)->fonts[i].fontID = txt->font_table->fonts[i].fontID;
-			if (txt->font_table->fonts[i].fontName)
-				(*out_desc)->fonts[i].fontName = gf_strdup(txt->font_table->fonts[i].fontName);
+		if (txt->font_table && txt->font_table->entry_count) {
+			(*out_desc)->font_count = txt->font_table->entry_count;
+			(*out_desc)->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord) * txt->font_table->entry_count);
+			for (i=0; i<txt->font_table->entry_count; i++) {
+				(*out_desc)->fonts[i].fontID = txt->font_table->fonts[i].fontID;
+				if (txt->font_table->fonts[i].fontName)
+					(*out_desc)->fonts[i].fontName = gf_strdup(txt->font_table->fonts[i].fontName);
+			}
 		}
 	}
 	return GF_OK;
 }
 
@@ -661,13 +663,16 @@ GF_TextSample *gf_isom_parse_text_sample(GF_BitStream *bs)
 		s->text[s->len+1] = 0;
 		gf_bs_read_data(bs, s->text, s->len);
 	}
 
 	while (gf_bs_available(bs)) {
-		GF_Box *a;
+		GF_Box *a = NULL;
 		GF_Err e = gf_isom_box_parse(&a, bs);
-		if (e) break;
+		if (e) {
+			if (a) gf_isom_box_del(a);
+			break;
+		}
 
 		switch (a->type) {
 		case GF_ISOM_BOX_TYPE_STYL:
 			if (s->styles) {
 				GF_TextStyleBox *st2 = (GF_TextStyleBox *)a;

Vulnerable code: 			names.vals[i] = gf_strdup(txt->text);
	
	
		



		
		
		
		
					if (add_tk) {
	
	
		//this may be quite long until we have a packet in case input pid is video encoding 
		

	
		(*out_desc)->font_count = txt->font_table->entry_count;
		(*out_desc)->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord) * txt->font_table->entry_count);
		for (i=0; i<txt->font_table->entry_count; i++) {
			(*out_desc)->fonts[i].fontID = txt->font_table->fonts[i].fontID;
			if (txt->font_table->fonts[i].fontName)
				(*out_desc)->fonts[i].fontName = gf_strdup(txt->font_table->fonts[i].fontName);
		GF_Box *a;
		if (e) break;
Fixed code: 			names.vals[i] = gf_strdup(txt->text ? txt->text : "");







					if (add_tk && p2->value.string_list.vals[j]) {


		//this may be quite long until we have a packet in case input pid is video encoding

			if (!ptr || !ptr->lsr_config || !ptr->lsr_config->hdr_size)
				return GF_ISOM_INVALID_MEDIA;

		if (txt->font_table && txt->font_table->entry_count) {
			(*out_desc)->font_count = txt->font_table->entry_count;
			(*out_desc)->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord) * txt->font_table->entry_count);
			for (i=0; i<txt->font_table->entry_count; i++) {
				(*out_desc)->fonts[i].fontID = txt->font_table->fonts[i].fontID;
				if (txt->font_table->fonts[i].fontName)
					(*out_desc)->fonts[i].fontName = gf_strdup(txt->font_table->fonts[i].fontName);
			}
		GF_Box *a = NULL;
		if (e) {
			if (a) gf_isom_box_del(a);
			break;
		}