getChannels() crashes on servers returning an empty channels array — the guard exists in process_trigger_result() but not here
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 84/100
Direzione di ricerca
Inizia in src/Pusher.php, in getChannels(), quindi confronta la gestione di channels con process_trigger_result(), che protegge già dalle risposte non costituite da oggetti. Esegui il metodo con un array channels vuoto e verifica che restituisca la forma dell'array documentata senza un TypeError; esegui i test rilevanti del progetto per confermare che il comportamento esistente rimanga intatto.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
getChannels() calls get_object_vars() without a type check, so a server response where channels is an empty JSON array crashes the client:
TypeError: get_object_vars(): Argument #1 ($object) must be of type object, array given
src/Pusher.php:664
The interesting part: this library already guards against exactly this, but only on one code path.
process_trigger_result() (added in #323, fixing #322) checks the type:
https://github.com/pusher/pusher-http-php/blob/master/src/Pusher.php#L1195-L1197
if (property_exists($result, 'channels') && is_object($result->channels)) {
$result->channels = get_object_vars($result->channels);
}
getChannels() does not:
https://github.com/pusher/pusher-http-php/blob/master/src/Pusher.php#L660-L666
public function getChannels(array $params = []): object
{
$result = $this->get('/channels', $params);
$result->channels = get_object_vars($result->channels);
return $result;
}
Why it happens in practice
Pusher-protocol implementations other than Pusher itself are common now (Reverb, Sockudo, Soketi). I hit this with Laravel Reverb v1.11.1, which serialises an empty channel list as [] instead of {} — I reported it there as laravel/reverb#402, and it should be fixed on their side too.
But the failure mode is worth guarding here regardless, because it is silent and intermittent: the response is an array only while no channel is occupied. One connected client turns the PHP array into a string-keyed map, json_encode emits an object, and the crash disappears. So it reproduces on idle systems and vanishes under load.
Measured side by side, same signed request:
Reverb → {"channels":[]}
Sockudo → {"channels":{}}
Suggestion
Apply the same guard that process_trigger_result() already uses:
$result->channels = is_object($result->channels) ? get_object_vars($result->channels) : (array) $result->channels;
This keeps the documented return shape (channels as an array of channel names) for every server, instead of a fatal error for some of them. Happy to send a PR.
Environment
- pusher/pusher-php-server ^7.2
- PHP 8.3
- Lingua principale
- PHP
- Stelle
- 1.5k
- Fork
- 315
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Issue simili
-
Add TuneIn-DirMon in the bot listForse già presa @liviuconcioiu l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
matomo-org/device-detector#8424 ·
I maintainer di solito rispondono entro 1 giorno
-
affecting 5.2 only affecting 5.3 only bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
moodle-an-hochschulen/moodle-theme_boost_union#1463 ·
I maintainer di solito rispondono entro 1 giorno
-
Course help wanted Sensei
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
woocommerce/woocommerce-paypal-payments#4838 ·
I maintainer di solito rispondono entro 1 giorno
-
sync-en
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
I maintainer di solito rispondono entro 2 giorni