CVE-2023-4756: Out-of-bounds Write (CWE-787)
value: Stack-based Buffer Overflow in GitHub repository gpac/gpac prior to 2.3-DEV.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2023-09-04T09:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/scene_manager/loader_bt.c
Commit date: 2023-09-04 09:35:27 +0200
Commit message: Fixed #2584

Diff: diff --git a/src/scene_manager/loader_bt.c b/src/scene_manager/loader_bt.c
index a376fa5e6bd..97256d5f8bc 100644
--- a/src/scene_manager/loader_bt.c
+++ b/src/scene_manager/loader_bt.c
@@ -132,28 +132,35 @@ static GF_Err gf_bt_report(GF_BTParser *parser, GF_Err e, char *format, ...)
 }
 
 
 void gf_bt_check_line(GF_BTParser *parser)
 {
-	while (1) {
+reload_line:
+	while (parser->line_pos < parser->line_size) {
 		switch (parser->line_buffer[parser->line_pos]) {
 		case ' ':
 		case '\t':
 		case '\n':
 		case '\r':
 			parser->line_pos++;
 			continue;
+		case '\0':
+			parser->line_pos = parser->line_size;
 		default:
 			break;
 		}
 		break;
 	}
 
-	if (parser->line_buffer[parser->line_pos]=='#') {
-		parser->line_size = parser->line_pos;
+	if (parser->line_pos < parser->line_size) {
+		if (parser->line_buffer[parser->line_pos]=='#') {
+			parser->line_size = parser->line_pos;
+		}
+		else if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') ) {
+			parser->line_size = parser->line_pos;
+		}
 	}
-	else if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') ) parser->line_size = parser->line_pos;
 
 	if (parser->line_size == parser->line_pos) {
 		/*string based input - done*/
 		if (!parser->gz_in) {
 			parser->done = 1;
@@ -403,14 +410,19 @@ next_line:
 				if (!found) break;
 			}
 		}
 	}
 	if (!parser->line_size) {
-		if (!gf_gzeof(parser->gz_in)) gf_bt_check_line(parser);
-		else parser->done = 1;
+		if (!gf_gzeof(parser->gz_in))
+			//avoid recursion
+			goto reload_line;
+		else
+			parser->done = 1;
 	}
-	else if (!parser->done && (parser->line_size == parser->line_pos)) gf_bt_check_line(parser);
+	else if (!parser->done && (parser->line_size == parser->line_pos))
+		//avoid recursion
+		goto reload_line;
 }
 
 void gf_bt_force_line(GF_BTParser *parser)
 {
 	parser->line_pos = parser->line_size;

Vulnerable code: 	while (1) {
	if (parser->line_buffer[parser->line_pos]=='#') {
		parser->line_size = parser->line_pos;
	else if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') ) parser->line_size = parser->line_pos;
		if (!gf_gzeof(parser->gz_in)) gf_bt_check_line(parser);
		else parser->done = 1;
	else if (!parser->done && (parser->line_size == parser->line_pos)) gf_bt_check_line(parser);
Fixed code: reload_line:
	while (parser->line_pos < parser->line_size) {
		case '\0':
			parser->line_pos = parser->line_size;
	if (parser->line_pos < parser->line_size) {
		if (parser->line_buffer[parser->line_pos]=='#') {
			parser->line_size = parser->line_pos;
		}
		else if ((parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/') ) {
			parser->line_size = parser->line_pos;
		}
		if (!gf_gzeof(parser->gz_in))
			//avoid recursion
			goto reload_line;
		else
			parser->done = 1;
	else if (!parser->done && (parser->line_size == parser->line_pos))
		//avoid recursion
		goto reload_line;