[PECL-CVS] [pecl-file_formats-yaml] php7: Fix some edge-case memory leaks and outstanding TODOs (#103)

[email protected] (Rasmus Lerdorf via GitHub) Sun, 5 Apr 2026 14:08:33 +0000
Newsgroups php.pecl.cvs
Message-ID <[email protected]>
Author: Rasmus Lerdorf (rlerdorf)
Committer: GitHub (web-flow)
Pusher: rlerdorf
Date: 2026-04-05T10:08:31-04:00

Commit: https://github.com/php/pecl-file_formats-yaml/commit/0b61dfbd865748132d62976ef3a600077ef50500
Raw diff: https://github.com/php/pecl-file_formats-yaml/commit/0b61dfbd865748132d62976ef3a600077ef50500.diff

Fix some edge-case memory leaks and outstanding TODOs (#103)

* Fix some edge-case memory leaks and outstanding TODOs

* get rid of the goto

* Fix Windows CI and init retval

Changed paths:
  M  .github/workflows/main.yml
  M  emit.c
  M  parse.c
  M  yaml.c


Diff:

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 2f9c8af..c86a311 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -98,7 +98,7 @@ jobs:
         uses: actions/checkout@v3
       - name: Setup PHP
         id: setup-php
-        uses: php/[email protected]
+        uses: php/setup-php-sdk@fix/invoke-webrequest-tls
         with:
           version: "${{ matrix.php-version }}"
           arch: "${{ matrix.arch }}"
diff --git a/emit.c b/emit.c
index ab7e46c..69b7f30 100644
--- a/emit.c
+++ b/emit.c
@@ -580,15 +580,14 @@ static int y_write_array(
 			/* emit key */
 			status = y_write_zval(state, &key_zval, NULL);
 			if (SUCCESS != status) {
-				return FAILURE;
+				break;
 			}
 		}
 
 		status = y_write_zval(state, elm, NULL);
 
-
 		if (SUCCESS != status) {
-			return FAILURE;
+			break;
 		}
 	} ZEND_HASH_FOREACH_END();
 
@@ -602,6 +601,10 @@ static int y_write_array(
 	}
 #endif
 
+	if (FAILURE == status) {
+		return FAILURE;
+	}
+
 	if (Y_ARRAY_SEQUENCE == array_type) {
 		status = yaml_sequence_end_event_initialize(&event);
 	} else {
@@ -747,6 +750,7 @@ y_write_object_callback (
 				" to contain a key named 'tag' with a string value",
 				clazz_name);
 		zend_string_release(str_key);
+		zval_ptr_dtor(&zret);
 		return FAILURE;
 	}
 	zend_string_release(str_key);
@@ -758,6 +762,7 @@ y_write_object_callback (
 				" to contain a key named 'data'",
 				clazz_name);
 		zend_string_release(str_key);
+		zval_ptr_dtor(&zret);
 		return FAILURE;
 	}
 	zend_string_release(str_key);
diff --git a/parse.c b/parse.c
index 17f70ba..c504cb3 100644
--- a/parse.c
+++ b/parse.c
@@ -149,8 +149,7 @@ void php_yaml_read_all(parser_state_t *state, zend_long *ndocs, zval *retval)
 	}
 
 	if (Y_PARSER_FAILURE == code) {
-		//TODO sdubois
-		//zval_ptr_dtor(&retval);
+		zval_ptr_dtor(retval);
 		ZVAL_UNDEF(retval);
 	}
 }
@@ -165,6 +164,8 @@ void php_yaml_read_partial(
 {
 	int code = Y_PARSER_CONTINUE;
 
+	ZVAL_UNDEF(retval);
+
 	while (Y_PARSER_CONTINUE == code) {
 
 		if (!NEXT_EVENT()) {
@@ -201,8 +202,8 @@ void php_yaml_read_partial(
 	}
 
 	if (Y_PARSER_FAILURE == code) {
-		//TODO sdubois
 		if (Z_TYPE_P(retval) != IS_UNDEF) {
+			zval_ptr_dtor(retval);
 			ZVAL_UNDEF(retval);
 		}
 	}
@@ -401,6 +402,8 @@ void handle_mapping(parser_state_t *state, zval *retval)
 		get_next_element(state, &value);
 
 		if (Z_TYPE(value) == IS_UNDEF) {
+			zval_ptr_dtor(retval);
+			ZVAL_UNDEF(retval);
 			yaml_event_delete(&src_event);
 			yaml_event_delete(&key_event);
 			zval_ptr_dtor(&key);
@@ -477,15 +480,15 @@ void handle_mapping(parser_state_t *state, zval *retval)
 	}
 
 	if (YAML_MAPPING_END_EVENT != state->event.type) {
-		//TODO Sean-Der
+		zval_ptr_dtor(retval);
 		ZVAL_UNDEF(retval);
 	}
 
-	if (NULL != retval && NULL != state->callbacks) {
+	if (Z_TYPE_P(retval) != IS_UNDEF && NULL != state->callbacks) {
 		/* apply callbacks to the collected node */
 		if (Y_FILTER_FAILURE == apply_filter(
 				retval, src_event, state->callbacks)) {
-			//TODO Sean-Der
+			zval_ptr_dtor(retval);
 			ZVAL_UNDEF(retval);
 		}
 	}
diff --git a/yaml.c b/yaml.c
index a91d4f1..7fb0a02 100644
--- a/yaml.c
+++ b/yaml.c
@@ -528,7 +528,7 @@ PHP_FUNCTION(yaml_parse_url)
 
 	if (zndocs != NULL) {
 		/* copy document count to var user sent in */
-		zval_dtor(zndocs);
+		zval_ptr_dtor(zndocs);
 		ZVAL_LONG(zndocs, ndocs);
 	}