From 47def8ce1db1fdbffcfc1f5bb11877a0e22d4b32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= <tim@tideways-gmbh.com>
Date: Sun, 3 May 2026 20:02:57 +0200
Subject: [PATCH] GHSA-96wq-48vp-hh57: [metaphone] Fix signed integer overflow
 of char array offset

Fixes GHSA-96wq-48vp-hh57
Fixes CVE-2026-7568
---
 ext/standard/metaphone.c                    |  6 +++---
 ext/standard/tests/GHSA-96wq-48vp-hh57.phpt | 22 +++++++++++++++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)
 create mode 100644 ext/standard/tests/GHSA-96wq-48vp-hh57.phpt

Index: php-7.4.33/ext/standard/metaphone.c
===================================================================
--- php-7.4.33.orig/ext/standard/metaphone.c
+++ php-7.4.33/ext/standard/metaphone.c
@@ -122,10 +122,10 @@ static const char _codes[26] =
 
 /* Allows us to safely look ahead an arbitrary # of letters */
 /* I probably could have just used strlen... */
-static char Lookahead(char *word, int how_far)
+static char Lookahead(char *word, size_t how_far)
 {
 	char letter_ahead = '\0';	/* null by default */
-	int idx;
+	size_t idx;
 	for (idx = 0; word[idx] != '\0' && idx < how_far; idx++);
 	/* Edge forward in the string... */
 
@@ -167,7 +167,7 @@ static char Lookahead(char *word, int ho
  */
 static int metaphone(unsigned char *word, size_t word_len, zend_long max_phonemes, zend_string **phoned_word, int traditional)
 {
-	int w_idx = 0;				/* point in the phonization we're at. */
+	size_t w_idx = 0;				/* point in the phonization we're at. */
 	size_t p_idx = 0;				/* end of the phoned phrase */
 	size_t max_buffer_len = 0;		/* maximum length of the destination buffer */
 
