@@ -254,7 +254,7 @@ protected function prepareStreamLines(Chunk $chunk): array
254254 $ lines = explode ("\n" , $ data );
255255
256256 if ($ data !== '' && ! str_ends_with ($ data , "\n" )) {
257- $ this ->streamBuffer = array_pop ($ lines ) ?? '' ;
257+ $ this ->streamBuffer = ( string ) array_pop ($ lines );
258258 if (strlen ($ this ->streamBuffer ) > self ::STREAM_BUFFER_MAX_BYTES ) {
259259 $ this ->streamBuffer = substr ($ this ->streamBuffer , -self ::STREAM_BUFFER_MAX_BYTES );
260260 }
@@ -285,9 +285,9 @@ protected function decodeSseJsonLine(string $line): ?array
285285 return null ;
286286 }
287287
288- $ json = json_decode ($ payload, true );
288+ $ json = $ this -> decodeJsonObject ($ payload );
289289
290- return is_array ( $ json) ? $ json : null ;
290+ return $ json ;
291291 }
292292
293293 /**
@@ -306,9 +306,9 @@ protected function decodeJsonOrSseLine(string $line): ?array
306306 return null ;
307307 }
308308
309- $ json = json_decode ($ payload, true );
309+ $ json = $ this -> decodeJsonObject ($ payload );
310310
311- return is_array ( $ json) ? $ json : null ;
311+ return $ json ;
312312 }
313313
314314 protected function appendStreamToken (string &$ block , string $ token , ?callable $ listener ): void
@@ -322,4 +322,26 @@ protected function appendStreamToken(string &$block, string $token, ?callable $l
322322 $ listener ($ token );
323323 }
324324 }
325+
326+ /**
327+ * Decode only JSON objects (associative arrays with string keys).
328+ *
329+ * @return array<string, mixed>|null
330+ */
331+ protected function decodeJsonObject (string $ jsonString ): ?array
332+ {
333+ $ decoded = json_decode ($ jsonString , true );
334+ if (! is_array ($ decoded ) || array_is_list ($ decoded )) {
335+ return null ;
336+ }
337+
338+ foreach (array_keys ($ decoded ) as $ key ) {
339+ if (! is_string ($ key )) {
340+ return null ;
341+ }
342+ }
343+
344+ /** @var array<string, mixed> $decoded */
345+ return $ decoded ;
346+ }
325347}
0 commit comments