-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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: Issue #9364 JSON config validation #10679
base: master
Are you sure you want to change the base?
Conversation
Triage notes:
|
Yeah, you're right, that would break existing users, will fix that tomorrow. |
…o fix/9364-validation
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.
Thanks @gsergey418alt for your contribution.
Could you add a flag to enable/disable strict config JSON parsing? e.g ipfs daemon --allow-unknown-config-fields
, true
by default.
This would allow existing users to pass that flag to continue using the same config, and would facilitate development when comparing different versions with the same config.
Docker commands still failing in CI, maybe some issue on your side? I don't see anything related to |
@guillaumemichel The existing users can keep using the same config, the validation is only done on the |
config/config.go
Outdated
// Convert config to a map, without using encoding/json. | ||
func ReflectToMap(conf interface{}) map[string]interface{} { |
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.
what is the reason to define a new function, and not use ToMap
defined above?
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's no way to get encoding/json
package (which is used in the ToMap function) to ignore the struct tags like json:",omitempty"
that hide the map fields. That means that the user wouldn't be able to set these fields, since this map is used to validate user's input from ipfs config
. Had to use the reflect
package to make that happen.
Same stuff with the docker commands |
I just checked locally, and only this PR is failing the docker sharness tests.
|
@guillaumemichel Yep, seen that test. I fixed the values to be valid, but it's still failing because the docker container isn't starting up. |
Turns out Just opened #10686 to address the outdated |
Awesome, good catch. |
I updated the @gsergey418alt could you please adapt |
Good work, but you would need a way to distinguish between in-config maps and structure. In my implementation, this was done via the "map" value of a field, so when the validator encounters this field, it knows that the user is trying to set nested value inside a map and it discards the rest of key. I think I should've named the function something like |
@gsergey418alt could you expand on that? I am not sure to understand the difference in practice. If your implementation works better, we can use it, I just want to cover all corner cases, and to test everything. |
@guillaumemichel If we run |
Ok I see. Would that work for maps that have nested types? |
@guillaumemichel Hmm, haven't thought about that actually. Maybe we could create a "ref" element inside that map that could be validated against if you want that covered. |
@guillaumemichel I've added sharness test for other data types, changed function name to |
Could you add a test for Have a nice weekend! |
@guillaumemichel I've solved the problem with validating structs inside maps, and it now works as expected. Added test for PublicGateways. |
Looks good thanks! A sharness test is still failing, probably due to the following config command:
Additionally, could you also add a test |
Added handling for interface{} in the config, like Plugins.Plugins.peerlog.Config.Enabled |
config/config.go
Outdated
if v, ok := cursor.(string); ok && v == "any" { | ||
return 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.
@gsergey418alt would that work? Using "any"
as key seems strange.
if v, ok := cursor.(string); ok && v == "any" { | |
return nil | |
} | |
if cursor == nil { | |
return 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.
I think I'm using it as a value here, try printing json.Marshal(confmap)
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.
what do you mean?
I just think using the string "any" is strange. Would it work to test for a nil pointer or empty string instead? And adapting ReflectToMap
accordingly.
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 are other empty strings in the output of ReflectToMap. Nil pointer could work, but "any" is perhaps more expressive e. g. this key contain anything, stop validating. I can change it to nil ptr if you want to.
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.
NVM, empty strings and nil values would also work
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.
NVM, It wouldn't work with empty strings, but it would still fail at a later stage.
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.
Changed "any" to nil
Fixes #9364. Disallow unknown fields when updating the config with
ipfs config
Before:
After: