Skip to content

Commit

Permalink
[Bugbash] Mixed refines to read-only object under typeof = object
Browse files Browse the repository at this point in the history
Summary:
It is not safe to refine `mixed` to `{[string] : mixed}` because this allows writes of any kind into the refined object, and we don't know what type of values the object holds. The only safe operation is to read `mixed` out of the object, so the properties must be read only.

```
function bad (x : mixed) {
  if (typeof x === "object" && x !== null) {
    x.a = 3;
  }
}

let obj : {a : string} = {a : "oops"};
bad(obj); // yikes
```

Reviewed By: mvitousek

Differential Revision: D14799387

fbshipit-source-id: 210ef1d98733b085b202dcbd4e1e83d69e707f08
  • Loading branch information
dsainati1 authored and facebook-github-bot committed Apr 5, 2019
1 parent ace3612 commit 0983bd0
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/typing/type_filter.ml
Expand Up @@ -331,7 +331,7 @@ let object_ cx t =
key = StrT.why r |> with_trust bogus_trust;
value = DefT (replace_reason_const MixedT.desc r, bogus_trust (), MixedT Mixed_everything);
dict_name = None;
dict_polarity = Neutral;
dict_polarity = Positive;
} in
let proto = ObjProtoT reason in
let obj = Obj_type.mk_with_proto cx reason ?dict proto in
Expand Down
2 changes: 1 addition & 1 deletion tests/refinements/mixed.js
Expand Up @@ -92,7 +92,7 @@ function false_(x: mixed) {

function obj2(x: mixed) {
if (typeof x === "object") {
(x: { [key: string]: mixed } | null);
(x: { +[key: string]: mixed } | null);
if (x !== null) {
(x['foo']: string); // error, mixed
}
Expand Down
9 changes: 9 additions & 0 deletions tests/refinements/mixed_object.js
@@ -0,0 +1,9 @@
// @flow
function bad (x : mixed) {
if (typeof x === "object" && x !== null) {
x.a = 3;
}
}

let obj : {a : string} = {a : "oops"};
bad(obj); // yikes
10 changes: 9 additions & 1 deletion tests/refinements/refinements.exp
Expand Up @@ -1238,6 +1238,14 @@ References:
^^^^^^ [2]


Error ---------------------------------------------------------------------------------------------- mixed_object.js:4:5

Cannot assign `3` to `x.a` because property `a` is not writable.

4| x.a = 3;
^^^


Error ------------------------------------------------------------------------------------------------------- not.js:5:5

Cannot perform arithmetic operation because null or undefined [1] is not a number.
Expand Down Expand Up @@ -3430,4 +3438,4 @@ Cannot perform arithmetic operation because undefined [1] is not a number.



Found 248 errors
Found 249 errors

0 comments on commit 0983bd0

Please sign in to comment.