Skip to content
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

util/gconv: compatibility for bool pointer #3764

Closed
qinyuguang opened this issue Sep 9, 2024 · 2 comments · Fixed by #3765
Closed

util/gconv: compatibility for bool pointer #3764

qinyuguang opened this issue Sep 9, 2024 · 2 comments · Fixed by #3765
Labels

Comments

@qinyuguang
Copy link
Contributor

qinyuguang commented Sep 9, 2024

What do you want to ask?

Code

trueValue := true
falseValue := false
type T struct {
    True     bool  `json:"true"`
    False    bool  `json:"false"`
    TruePtr  *bool `json:"true_ptr"`
    FalsePtr *bool `json:"false_ptr"`
}
m := g.Map{
    "true":      trueValue,
    "false":     falseValue,
    "true_ptr":  &trueValue,
    "false_ptr": &falseValue,
}
t := &T{}
_ = gconv.Struct(m, &t)
gutil.DumpWithType(m, t)

v2.7.2 output

map[string]interface {}(4) {                                                                                                                                                                        
    string("false_ptr"): bool(false),                                                                                                                                                               
    string("true"):      bool(true),                                                                                                                                                                
    string("false"):     bool(false),                                                                                                                                                               
    string("true_ptr"):  bool(true),                                                                                                                                                                
}                                                                                                                                                                                                   
*main.T(4) {                                                                                                                                                                                        
    True:     bool(true),                                                                                                                                                                           
    False:    bool(false),                                                                                                                                                                          
    TruePtr:  bool(true),                                                                                                                                                                           
    FalsePtr: bool(false),                                                                                                                                                                          
} 

v2.7.3 output

map[string]interface {}(4) {                                                                                                                                                                        
    string("false_ptr"): bool(false),                                                                                                                                                               
    string("true"):      bool(true),                                                                                                                                                                
    string("false"):     bool(false),                                                                                                                                                               
    string("true_ptr"):  bool(true),                                                                                                                                                                
}                                                                                                                                                                                                   
*main.T(4) {                                                                                                                                                                                        
    True:     bool(true),                                                                                                                                                                           
    False:    bool(false),                                                                                                                                                                          
    TruePtr:  bool(true),                                                                                                                                                                           
    FalsePtr: bool(true),                                                                                                                                                                           
} 

Question

Need maintain compatibility when upgrading minor versions?

@wln32
Copy link
Member

wln32 commented Sep 11, 2024

@qinyuguang 老版本的代码在没有改造前,对于 bool 类型的转换是以下流程
对于 *bool 类型,判断了是否为指针,如果是直接返回,且是浅复制
image

新版本的改造代码直接走了gconv.Bool函数的逻辑,里面对于指针的处理是以下流程

注册bool转换函数的代码
image

gconv.Bool函数的实现----只要指针非nil,就全部为true,这个逻辑理论上是错误的,
image

可能会导致以下情况

var f = new(bool) // f = &false 实际

var v= gconv.Bool(f)
fmt.Println(v)
// output: true

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


@qinyuguang Before the old version of the code was modified, the conversion process for bool type was as follows
For the *bool type, it is judged whether it is a pointer, if it is returned directly, and it is a shallow copy
image

The new version of the modified code directly uses the logic of the gconv.Bool function. The processing of pointers is as follows:

Code to register bool conversion function
image

The implementation of the gconv.Bool function - as long as the pointer is non-nil, all are true. This logic is theoretically wrong.
image

This may lead to the following situations

var f = new(bool) // f = &false actual

var v= gconv.Bool(f)
fmt.Println(v)
// output: true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants