New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 635987 link

Starred by 1 user

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Null WTFString automatically convert to empty if the mojom field is defined as non-nullable?

Project Member Reported by yzshen@chromium.org, Aug 9 2016

Issue description

(Thanks Darin for the suggestion!)

It is easy for developers to accidentally pass a null WTFString to a non-nullable mojom string field because:
- WTFString default constructor initializes to null.
- In most cases, null WTFString acts like an empty string (e.g., it returns 0 for length, etc.)
- When a null WTFString is passed to a non-nullable field, we will get an assert in debug build and a validation error at the receiving side. But this is a run-time check so developers may miss some corner cases during testing.

On the other hand, making WTFString a special case may lead to confusion about how mojo handles nullability in general. Another idea is to completely change how we handle nullability. For example, we could make the change so that whenever the bindings receive null for a non-nullable field, it automatically deserializes the value as an "empty" object (which is sometimes different from default-constructed, so it will require us to extend the StructTraits/UnionTraits/etc. interface.)

At the moment, I am inclined to leaving it unchanged and waiting for more feedback. Our crash server will collect reports of bad messages, including nullability violation. So we can see how big the problem is in the field.

WDYT? Thanks!







 

Comment 1 by darin@chromium.org, Aug 9 2016

When wiring a Mojom-defined interface up to Blink code, I find that it is hard to know if a String I get from Blink can ever be null. The type definition implies that it can sometimes be null. As a result, I think I need to write code like this at every callsite:

  mojom_interface->CallMethod(string.isNull() ? emptyString() : string);

That seems pretty unfortunate.

If null were promoted to empty when passed to a non-nullable field, then it would be a lot simpler.

I agree though that we should be careful here. This could be a choice that we might regret.

I'm also open to the idea of special-casing strings. Maybe objects should work as they do today.

Note: This same issue doesn't apply to WTF::Vector as it does not have a null state.
Yeah, agreed that this is unfortunate.

A few other possible solutions that may also worth considering:

1) use "string?" for fields that we would like to pass WTFString (although in general it seems a little unfortunate to change the mojom type to fit the bindings type)

2) create a NonNullWTFString wrapper (a better name needed...), which can be converted to/from WTFString implicitly. So we can generated bindings like:

virtual CallMethod(const NonNullWTFString& input);

And then call it with a WTFString directly. The conversion will take care of promoting null WTFString to empty.



Comment 3 by darin@chromium.org, Aug 10 2016

> virtual CallMethod(const NonNullWTFString& input);

That seems like it would work on the caller side, but Mojom interfaces are also used on the implementation side. It seems like on the implementation side, we'd want CallMethod to take just a "const String&" instead right?

Using "string?" for these seems less satisfying and still leads to having to write code to handle null.

Hmm...

Comment 4 by yzshen@chromium.org, Aug 10 2016

If the implementation is also in blink, I would imagine that the interface is the same. We could support implicit cast from NonNullWTFString to WTFString, so it should have a minimal impact on the implementation code.

I am not super happy with introducing another string type. So far all the solutions seem to have some drawback. :/ I will think harder...


Components: Internals>Mojo
Components: -Internals>Mojo Internals>Mojo>Bindings
Cc: -roc...@chromium.org rockot@google.com
Cc: -yzshen@chromium.org
Status: Available (was: Untriaged)
Still seems like a valid request, so triaging as such.

I kind of think that if we treat a null WTFString as empty in any context, we must treat it as empty in every context. So e.g. even if passed for a "string?" field, the field should take on the value of an empty string rather than null. 

Otherwise this is bound to be very confusing behavior.

Sign in to add a comment