loading...
Cover image for DeepCode’s Top Findings#4: JavaScript Attribute Access on NULL
DeepCode.AI

DeepCode’s Top Findings#4: JavaScript Attribute Access on NULL

cu_0xff profile image cu_0xff 🇪🇺 Originally published at Medium ・3 min read

DeepCode offers an AI-based Static Program Analysis for Java, Javascript and Typescript, and Python. You might know, DeepCode uses thousands of open source repos to train our engine. We asked the engine team to provide some stats on the findings. For the top suggestions from our engine, we want to provide an introduction and give some background in this series of blog articles. This is #4 in this series...

Language: JavaScript
Defect: Attribute Access On Null (Category General 3)
Diagnose: – Null reference via read access / Conditional execution context determines an accessed variable to hold null.

You can find below example by in Facebook’s React here.

Background

Let us have a look at the code snippet of the aforementioned example (sorry I know it is a bit lengthy) and follow the variable maybeInstance:

...
/**
    * This function sends props straight to native. They will not participate in
    * future diff process - this means that if you do not include them in the
    * next render, they will remain active (see [Direct
    * Manipulation](docs/direct-manipulation.html)).
    */
setNativeProps: function(nativeProps: Object) {
    // Class components don't have viewConfig -> validateAttributes.
    // Nor does it make sense to set native props on a non-native component.
    // Instead, find the nearest host component and set props on it.
    // Use findNodeHandle() rather than findNodeHandle() because
    // We want the instance/wrapper (not the native tag).
    let maybeInstance;

    // Fiber errors if findNodeHandle is called for an umounted component.
    // Tests using ReactTestRenderer will trigger this case indirectly.
    // Mimicking stack behavior, we should silently ignore this case.
    // TODO Fix ReactTestRenderer so we can remove this try/catch.
    try {
        maybeInstance = findHostInstance(this); 
    } catch (error) {}

    // If there is no host component beneath this we should fail silently.
    // This is not an error; it could mean a class component rendered null.
    if (maybeInstance == null) {
        return;
    }

    if (maybeInstance.canonical) {
        warningWithoutStack(
            false,
            'Warning: setNativeProps is not currently supported in Fabric',
        );
        return;
    }

    const nativeTag =
    maybeInstance._nativeTag || maybeInstance.canonical._nativeTag;
    const viewConfig: ReactNativeBaseComponentViewConfig<> =
    maybeInstance.viewConfig || maybeInstance.canonical.viewConfig;
...

If you look at the code, you see the variable is assigned to the result of a function ( findHostInstance() ) and exceptions are caught but not handled. Well, as the comment says: TODO.

Next, we have an if-statement which will execute the return if our variable is either null or unknown. We could argue about the == versus the === and handling the return in the catch but we leave this for another day. So, from now on we know maybeInstance is not null nor unknown.

The next if-statement tests if there is a property called canonical in maybeInstance that exists and is not null, unknown, false, or 0 as these will trigger this if and we will return from this function. So, now we know that maybeInstance.canonical is a falsy literal.

Finally, the code checks whether there is a property maybeInstance._nativeTag or a property maybeInstance.canonical._nativeTag. What happens now? JavaScript will try to interpret both sides of the OR. We know maybeInstance.canonical is either false or 0 and the program tests if these values have a property called _nativeTag. In this case, the program does not crash but this is for sure also not intended. It is very likely maybeInstance.canonical will result in null or unknown which will crash the program (Uncaught TypeError). And the line next does the same thing again...

As you saw this is not an easy thing to detect for a Static Program Analysis as you have to do a pointer analysis of a complex object. Give it a try on your own code at deepcode.ai

CU

0xff

Posted on by:

cu_0xff profile

cu_0xff 🇪🇺

@cu_0xff

Veteran in IT, Xoogler, Ex-Microsoft, works in Static Program Analysis

DeepCode.AI

DeepCode learns from GitHub project data to give developers AI-powered code reviews

Discussion

markdown guide