-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
new
constructors for WebIDL bindings introduce undefined behavior by not setting default values
#3937
Comments
It is not really an undefined behavior - they just create an empty object with no fields assigned. This is valid, and the defaults are applied at the receiver end. |
@MOZGIII I don't think that's the spirit of the WebIDL dictionary definitions. In that case having the concept of a Also, WebIDL APIs that return dictionaries always have the properties set that are not marked with Initializing these fields properly would make the consumer side much more streamlined. If, for some reason, you are not interested in initializing the fields fully, you could still manually call |
I'm definitely not an expert in JS/Web APIs, but I believe there are some misconceptions here. WebIDL dictionary and enum types are not translated to JS by web browsers. So when using these types in JS in the browser they are plain objects (not entirely sure about the terminology) and therefor don't contain default values. In comparison, WebIDL interface types do get a corresponding JS class which can be instantiated. While I do understand where this is coming from, unfortunately I might even dare to say that On a side note, as there is often no way to actually query the defaults, we can't really provide them. While it is true that we could follow the spec here, not all browsers follow the spec and it doesn't actually expose if the default was set or not, which does sometimes make a difference, according to the spec. And yes, #3933 has to return I'm going to go ahead and close this, but please continue the discussed here if there is more left unsaid or if I was wrong about something. |
Describe the Bug
The definitions for WebIDL dictionaries contain information if fields are optional or required by prefixing them with
required
or marking the type?
. However, there's a third option: fields can be neitherrequired
nor?
, but have a default value after=
.Currently, code generation for constructor bindings does not set default values in the body of the
new
function. Therefore, creating a dictionary withnew()
and immediately reading a field that should have a default value is undefined behavior.Steps to Reproduce
E.g. for the first dictionary declaration I could find going alphabetically in the enabled WebIDLs that uses default values:
wasm-bindgen/crates/web-sys/webidls/enabled/AnalyserNode.webidl
Lines 13 to 18 in e78db23
This example is using the getters as implemented in #3933, but the same case can be constructed by many Web APIs that take a dictionary with properties containing default values as argument.
Expected Behavior
Actual Behavior
Additional Context
The faulty generated code for
AnalyserOptions::new
that does not set default values:wasm-bindgen/crates/web-sys/src/features/gen_AnalyserOptions.rs
Lines 30 to 38 in e78db23
I discovered this by working on WebIDL dictionary getters in #3933 and thinking about the implications of unsetting dictionary values in #3921 (comment).
Not allowing to safely read properties that are known to exist on a dictionary would require using
Option
in return values of property getters and require to be unnecessarily defensive when reading them.The text was updated successfully, but these errors were encountered: