mirror of
https://github.com/dunglas/frankenphp.git
synced 2025-12-24 13:38:11 +08:00
fix: crash when a string is passed for the topics parameter of the mercure_publish() function (#2021)
This commit is contained in:
@@ -47,6 +47,7 @@ type testOptions struct {
|
||||
realServer bool
|
||||
logger *slog.Logger
|
||||
initOpts []frankenphp.Option
|
||||
requestOpts []frankenphp.RequestOption
|
||||
phpIni map[string]string
|
||||
}
|
||||
|
||||
@@ -82,8 +83,10 @@ func runTest(t *testing.T, test func(func(http.ResponseWriter, *http.Request), *
|
||||
require.NoError(t, err)
|
||||
defer frankenphp.Shutdown()
|
||||
|
||||
opts.requestOpts = append(opts.requestOpts, frankenphp.WithRequestDocumentRoot(testDataDir, false))
|
||||
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := frankenphp.NewRequestWithContext(r, frankenphp.WithRequestDocumentRoot(testDataDir, false))
|
||||
req, err := frankenphp.NewRequestWithContext(r, opts.requestOpts...)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = frankenphp.ServeHTTP(w, req)
|
||||
@@ -1003,6 +1006,7 @@ func FuzzRequest(f *testing.F) {
|
||||
if strings.Contains(req.URL.Path, "\x00") {
|
||||
assert.Equal(t, 400, resp.StatusCode)
|
||||
assert.Contains(t, body, "invalid request path")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
10
mercure.go
10
mercure.go
@@ -17,7 +17,7 @@ type mercureContext struct {
|
||||
}
|
||||
|
||||
//export go_mercure_publish
|
||||
func go_mercure_publish(threadIndex C.uintptr_t, topics *C.struct__zval_struct, data unsafe.Pointer, private bool, id, typ unsafe.Pointer, retry uint64) (generatedID *C.zend_string, error C.short) {
|
||||
func go_mercure_publish(threadIndex C.uintptr_t, topics *C.struct__zval_struct, data *C.zend_string, private bool, id, typ *C.zend_string, retry uint64) (generatedID *C.zend_string, error C.short) {
|
||||
thread := phpThreads[threadIndex]
|
||||
ctx := thread.context()
|
||||
fc := thread.frankenPHPContext()
|
||||
@@ -32,10 +32,10 @@ func go_mercure_publish(threadIndex C.uintptr_t, topics *C.struct__zval_struct,
|
||||
|
||||
u := &mercure.Update{
|
||||
Event: mercure.Event{
|
||||
Data: GoString(data),
|
||||
ID: GoString(id),
|
||||
Data: GoString(unsafe.Pointer(data)),
|
||||
ID: GoString(unsafe.Pointer(id)),
|
||||
Retry: retry,
|
||||
Type: GoString(typ),
|
||||
Type: GoString(unsafe.Pointer(typ)),
|
||||
},
|
||||
Private: private,
|
||||
}
|
||||
@@ -43,7 +43,7 @@ func go_mercure_publish(threadIndex C.uintptr_t, topics *C.struct__zval_struct,
|
||||
zvalType := C.zval_get_type(topics)
|
||||
switch zvalType {
|
||||
case C.IS_STRING:
|
||||
u.Topics = []string{GoString(unsafe.Pointer(topics))}
|
||||
u.Topics = []string{GoString(unsafe.Pointer(*(**C.zend_string)(unsafe.Pointer(&topics.value[0]))))}
|
||||
case C.IS_ARRAY:
|
||||
ts, err := GoPackedArray[string](unsafe.Pointer(topics))
|
||||
if err != nil {
|
||||
|
||||
32
mercure_test.go
Normal file
32
mercure_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
//go:build !nomercure
|
||||
|
||||
package frankenphp_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
"github.com/dunglas/mercure"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMercurePublish_module(t *testing.T) { testMercurePublish(t, &testOptions{}) }
|
||||
func TestMercurePublish_worker(t *testing.T) {
|
||||
testMercurePublish(t, &testOptions{workerScript: "index.php"})
|
||||
}
|
||||
func testMercurePublish(t *testing.T, opts *testOptions) {
|
||||
h, err := mercure.NewHub(t.Context(), mercure.WithTransport(mercure.NewLocalTransport(mercure.NewSubscriberList(0))))
|
||||
require.NoError(t, err)
|
||||
|
||||
opts.requestOpts = []frankenphp.RequestOption{frankenphp.WithMercureHub(h)}
|
||||
|
||||
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
|
||||
body, _ := testGet(fmt.Sprintf("https://example.com/mercure-publish.php?i=%d", i), handler, t)
|
||||
assert.Contains(t, body, "update 1: ")
|
||||
assert.Contains(t, body, "update 2: ")
|
||||
}, opts)
|
||||
}
|
||||
1
testdata/flush.php
vendored
1
testdata/flush.php
vendored
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
|
||||
require_once __DIR__.'/_executor.php';
|
||||
|
||||
return function () {
|
||||
|
||||
8
testdata/mercure-publish.php
vendored
Normal file
8
testdata/mercure-publish.php
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/_executor.php';
|
||||
|
||||
return function () {
|
||||
echo "update 1: " . mercure_publish('foo', 'bar', true, 'myid', 'mytype', 10) . PHP_EOL;
|
||||
echo "update 2: " . mercure_publish(['baz', 'bar']) . PHP_EOL;
|
||||
};
|
||||
Reference in New Issue
Block a user