-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(net/ghttp): 修复当上传文件参数的类型为string时panic的问题 #4203
base: master
Are you sure you want to change the base?
Conversation
I don’t know. I went around for a long time when I changed this, and I don’t know if this solution is reasonable. |
Like orm, you can define a converter for the ghttp package separately, which is not shared with gconv. You can replace all the places in the ghttp package that are currently used with ghttp with the custom converter in ghttp. It is mentioned in issue #2913 that currently, for parameter conversion errors, ghttp directly returns the default value and does not return an error. |
// init initializes the type converters for *UploadFile. | ||
func init() { | ||
_ = gconv.RegisterTypeConverterFunc(stringToUploadFile) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hailaz @wln32 这里不应该注册全局的转换函数,并且目前针对基础类型的转换函数也只能在结构体属性中生效。我建议是修改
gconv
组件中相关的转换函数,避免panic,而是返回error。我刚跟了一下代码,具体问题应该出在这
convertedValue = reflect.ValueOf(result).Convert(referReflectValue.Type()).Interface() ,但是解决方案的话,还需要进一步看看。
避免panic,而是返回error
不能认同这样的处理逻辑,返回error,会丢掉原来的信息,使得问题定位困难,最佳解决方案应是在ghttp包定义一个converter,ghttp中所有的转换都调用converter来做,而不是直接调用gconv,然后在针对string=>*UploadFile 注册一个转换函数即可
另gconv中有几处defer完全是多余的,本来转换出错了,立马panic即可,完全没必要再包装error,你硬是在defer中又处理了一次,给人看上去的感觉就是非要转换成功不可,这样的做法有时会成功,有时却会失败,而且这样会丧失掉原来的错误信息,我可以举个例子
package main
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/util/gconv"
)
func stringToInt(src string) (dst *[]int, err error) {
panic("stringToInt")
}
type Value struct {
V []int
}
func main() {
err := gconv.RegisterTypeConverterFunc(stringToInt)
if err != nil {
panic(err)
}
var dst Value
err = gconv.Scan(map[string]any{
"V": "[1,2,3]",
}, &dst)
fmt.Println(err)
fmt.Println(dst)
}
输出
nil
{[1 2 3]}
上面代码中的逻辑,即使stringToInt中panic,也能转换成功,看起来匪夷所思,上面代码中转换也不是走正常的逻辑,而是bindVarToStructField中的defer,里面又调用了bindVarToReflectValue,而"[1,2,3]"符合json格式字符串,所以走的是json.Unmarshal这样的逻辑,如果我换一个不符合json格式的,那就会失败,同时也不会有error
既然选择了注册自定义类型这个方式,为什么不把框架中非标准库的类型解耦出来,使用注册的方式在自定义类型所在的包进行注册,也能同时简化gconv中的逻辑。 |
Since you have chosen to register a custom type, why not decouple the non-standard library types in the framework and register in the package where the custom type is located by registering, which can also simplify the logic in gconv. |
这个自动翻译真的很影响交流,现在翻译插件已经很常见了,真的没有必要自动翻译。有心人根本不会因为没有翻译而不交流 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request fixes a panic issue when the file upload parameter is provided as a string rather than the expected file type. It adds a new test case to validate the error response and implements a custom type converter to safely handle string inputs.
- Added a new unit test (Test_Issue4193) to verify proper error messaging when a file parameter is a string.
- Registered a custom type converter (stringToUploadFile) and updated the Save method to check for a nil FileHeader.
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
net/ghttp/ghttp_z_unit_issue_test.go | Added a new test to ensure proper handling of string-based uploads. |
net/ghttp/ghttp_request_param_file.go | Registered a type converter and added a nil check for FileHeader in Save. |
Comments suppressed due to low confidence (1)
net/ghttp/ghttp_z_unit_issue_test.go:746
- Using time.Sleep to wait for the server startup may cause flaky tests on slower systems; consider using a synchronization mechanism to ensure the server is ready before sending requests.
time.Sleep(100 * time.Millisecond)
@@ -36,13 +42,18 @@ func (f UploadFile) MarshalJSON() ([]byte, error) { | |||
// UploadFiles is an array type of *UploadFile. | |||
type UploadFiles []*UploadFile | |||
|
|||
// stringToUploadFile is a custom type converter for converting string to *ghttp.UploadFile. | |||
func stringToUploadFile(in string) (*UploadFile, error) { | |||
return &UploadFile{}, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'stringToUploadFile' converter always returns an empty UploadFile without validating the input, which could lead to unexpected behavior. Consider validating the input string and returning an error for invalid values.
return &UploadFile{}, nil | |
if in == "" { | |
return nil, gerror.NewCode(gcode.CodeInvalidParameter, "input string is empty") | |
} | |
fileHeader := &multipart.FileHeader{ | |
Filename: in, | |
} | |
return &UploadFile{FileHeader: fileHeader}, nil |
Copilot is powered by AI, so mistakes are possible. Review output carefully before use.
Fixes #4193