Skip to content

Commit 1fbabf9

Browse files
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.
1 parent 2fa7663 commit 1fbabf9

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

internal/extgen/cfile_phpmethod_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,32 @@ func TestCFile_PHP_METHOD_Integration(t *testing.T) {
185185
require.NotContains(t, fullContent, old, "Did not expect to find old declaration %q in full C file content", old)
186186
}
187187
}
188+
189+
func TestCFile_ClassMethodStringReturn(t *testing.T) {
190+
generator := &Generator{
191+
BaseName: "test_extension",
192+
Classes: []phpClass{
193+
{
194+
Name: "TestClass",
195+
GoStruct: "TestClass",
196+
Methods: []phpClassMethod{
197+
{
198+
Name: "getString",
199+
PhpName: "getString",
200+
ReturnType: "string",
201+
ClassName: "TestClass",
202+
},
203+
},
204+
},
205+
},
206+
BuildDir: t.TempDir(),
207+
}
208+
209+
cFileGen := cFileGenerator{generator: generator}
210+
content, err := cFileGen.getTemplateContent()
211+
require.NoError(t, err)
212+
213+
require.Contains(t, content, "if (result)", "Expected NULL check for string return")
214+
require.Contains(t, content, "RETURN_STR(result)", "Expected RETURN_STR macro")
215+
require.Contains(t, content, "RETURN_EMPTY_STRING()", "Expected RETURN_EMPTY_STRING fallback")
216+
}

internal/extgen/templates/extension.c.tpl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ PHP_METHOD({{namespacedClassName $.Namespace .ClassName}}, {{.PhpName}}) {
114114
{{- if ne .ReturnType "void"}}
115115
{{- if eq .ReturnType "string"}}
116116
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}});
117-
RETURN_STR(result);
117+
if (result) {
118+
RETURN_STR(result);
119+
}
120+
RETURN_EMPTY_STRING();
118121
{{- else if eq .ReturnType "int"}}
119122
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}});
120123
RETURN_LONG(result);

0 commit comments

Comments
 (0)