fix(extgen): use RETURN_EMPTY_STRING() when returning empty string (#2049)

One last bug spotted by #1984, empty strings should be returned using
`RETURN_EMPTY_STRING()` or it may segfault.
This commit is contained in:
Alexandre Daubois
2025-12-01 15:43:45 +01:00
committed by GitHub
parent 2fa7663d3b
commit 1fbabf91c9
2 changed files with 33 additions and 1 deletions

View File

@@ -185,3 +185,32 @@ func TestCFile_PHP_METHOD_Integration(t *testing.T) {
require.NotContains(t, fullContent, old, "Did not expect to find old declaration %q in full C file content", old)
}
}
func TestCFile_ClassMethodStringReturn(t *testing.T) {
generator := &Generator{
BaseName: "test_extension",
Classes: []phpClass{
{
Name: "TestClass",
GoStruct: "TestClass",
Methods: []phpClassMethod{
{
Name: "getString",
PhpName: "getString",
ReturnType: "string",
ClassName: "TestClass",
},
},
},
},
BuildDir: t.TempDir(),
}
cFileGen := cFileGenerator{generator: generator}
content, err := cFileGen.getTemplateContent()
require.NoError(t, err)
require.Contains(t, content, "if (result)", "Expected NULL check for string return")
require.Contains(t, content, "RETURN_STR(result)", "Expected RETURN_STR macro")
require.Contains(t, content, "RETURN_EMPTY_STRING()", "Expected RETURN_EMPTY_STRING fallback")
}

View File

@@ -114,7 +114,10 @@ PHP_METHOD({{namespacedClassName $.Namespace .ClassName}}, {{.PhpName}}) {
{{- if ne .ReturnType "void"}}
{{- if eq .ReturnType "string"}}
zend_string* result = {{.Name}}_wrapper(intern->go_handle{{if .Params}}{{range .Params}}, {{if .IsNullable}}{{if eq .PhpType "string"}}{{.Name}}_is_null ? NULL : {{.Name}}{{else if eq .PhpType "int"}}{{.Name}}_is_null ? NULL : &{{.Name}}{{else if eq .PhpType "float"}}{{.Name}}_is_null ? NULL : &{{.Name}}{{else if eq .PhpType "bool"}}{{.Name}}_is_null ? NULL : &{{.Name}}{{else if eq .PhpType "array"}}{{.Name}}{{end}}{{else}}{{.Name}}{{end}}{{end}}{{end}});
RETURN_STR(result);
if (result) {
RETURN_STR(result);
}
RETURN_EMPTY_STRING();
{{- else if eq .ReturnType "int"}}
zend_long result = {{.Name}}_wrapper(intern->go_handle{{if .Params}}{{range .Params}}, {{if .IsNullable}}{{if eq .PhpType "string"}}{{.Name}}_is_null ? NULL : {{.Name}}{{else if eq .PhpType "int"}}{{.Name}}_is_null ? NULL : &{{.Name}}{{else if eq .PhpType "float"}}{{.Name}}_is_null ? NULL : &{{.Name}}{{else if eq .PhpType "bool"}}{{.Name}}_is_null ? NULL : &{{.Name}}{{else if eq .PhpType "array"}}{{.Name}}{{end}}{{else}}{{if eq .PhpType "array"}}{{.Name}}{{else}}(long){{.Name}}{{end}}{{end}}{{end}}{{end}});
RETURN_LONG(result);