-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
fix(net/ghttp): 修复当上传文件参数的类型为string时panic的问题 #4203
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -19,9 +19,15 @@ import ( | |||||||||||||||||
"github.com/gogf/gf/v2/internal/json" | ||||||||||||||||||
"github.com/gogf/gf/v2/os/gfile" | ||||||||||||||||||
"github.com/gogf/gf/v2/os/gtime" | ||||||||||||||||||
"github.com/gogf/gf/v2/util/gconv" | ||||||||||||||||||
"github.com/gogf/gf/v2/util/grand" | ||||||||||||||||||
) | ||||||||||||||||||
|
||||||||||||||||||
// init initializes the type converters for *UploadFile. | ||||||||||||||||||
func init() { | ||||||||||||||||||
_ = gconv.RegisterTypeConverterFunc(stringToUploadFile) | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
// UploadFile wraps the multipart uploading file with more and convenient features. | ||||||||||||||||||
type UploadFile struct { | ||||||||||||||||||
*multipart.FileHeader `json:"-"` | ||||||||||||||||||
|
@@ -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 commentThe 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.
Suggested change
Copilot is powered by AI, so mistakes are possible. Review output carefully before use. Positive FeedbackNegative Feedback |
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
// Save saves the single uploading file to directory path and returns the saved file name. | ||||||||||||||||||
// | ||||||||||||||||||
// The parameter `dirPath` should be a directory path, or it returns error. | ||||||||||||||||||
// | ||||||||||||||||||
// Note that it will OVERWRITE the target file if there's already a same name file exist. | ||||||||||||||||||
func (f *UploadFile) Save(dirPath string, randomlyRename ...bool) (filename string, err error) { | ||||||||||||||||||
if f == nil { | ||||||||||||||||||
if f == nil || f.FileHeader == nil { | ||||||||||||||||||
return "", gerror.NewCode( | ||||||||||||||||||
gcode.CodeMissingParameter, | ||||||||||||||||||
"file is empty, maybe you retrieve it from invalid field name or form enctype", | ||||||||||||||||||
|
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。我刚跟了一下代码,具体问题应该出在这gf/util/gconv/internal/converter/converter_convert.go
Line 459 in bc1e101
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.
不能认同这样的处理逻辑,返回error,会丢掉原来的信息,使得问题定位困难,最佳解决方案应是在ghttp包定义一个converter,ghttp中所有的转换都调用converter来做,而不是直接调用gconv,然后在针对string=>*UploadFile 注册一个转换函数即可
另gconv中有几处defer完全是多余的,本来转换出错了,立马panic即可,完全没必要再包装error,你硬是在defer中又处理了一次,给人看上去的感觉就是非要转换成功不可,这样的做法有时会成功,有时却会失败,而且这样会丧失掉原来的错误信息,我可以举个例子
输出
nil
{[1 2 3]}
上面代码中的逻辑,即使stringToInt中panic,也能转换成功,看起来匪夷所思,上面代码中转换也不是走正常的逻辑,而是bindVarToStructField中的defer,里面又调用了bindVarToReflectValue,而"[1,2,3]"符合json格式字符串,所以走的是json.Unmarshal这样的逻辑,如果我换一个不符合json格式的,那就会失败,同时也不会有error