Bug 202155 - Address static analysis warning in UTextProviderLatin1.cpp: Array access results in a null pointer dereference
Summary: Address static analysis warning in UTextProviderLatin1.cpp: Array access resu...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Web Template Framework (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Keith Rollin
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-09-24 12:25 PDT by Keith Rollin
Modified: 2019-09-25 23:41 PDT (History)
11 users (show)

See Also:


Attachments
Patch (2.26 KB, patch)
2019-09-24 12:28 PDT, Keith Rollin
no flags Details | Formatted Diff | Diff
Patch (2.53 KB, patch)
2019-09-25 20:27 PDT, Keith Rollin
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Keith Rollin 2019-09-24 12:25:41 PDT
Xcode's static analysis reports:

    UTextProviderLatin1.cpp -> darin, myles
    
    /Volumes/Data/dev/webkit/branches/static-analysis/OpenSource/Source/WTF/wtf/text/icu/UTextProviderLatin1.cpp:185:22: warning: Array access (from variable 'dest') results in a null pointer dereference
            dest[length] = 0;
            ~~~~         ^

This seems to be a false positive. Earlier checks involving "destCapacity" will exit the function if "destCapacity" is negative, or if "dest" is NULL and "destCapacity" is positive. Therefore, if "dest" is NULL, we will only enter if "destCapacity" is exactly zero. Further, there is a test just above the cited assignment that will never be true if "destCapacity" is zero. Therefore, the cited assignment will not be executed if "dest" is NULL. Address this by convincing the static analyzer of this with an ASSERT statement.
Comment 1 Radar WebKit Bug Importer 2019-09-24 12:26:02 PDT
<rdar://problem/55672422>
Comment 2 Keith Rollin 2019-09-24 12:28:14 PDT
Created attachment 379466 [details]
Patch
Comment 3 Geoffrey Garen 2019-09-24 13:32:23 PDT
Comment on attachment 379466 [details]
Patch

Is this really a false positive, or does it indicate that the preceding "if (destCapacity > 0 && !dest)" clause is incorrect? (It seems like the early check for "|| (!dest && destCapacity > 0)" should make the check for "if (destCapacity > 0 && !dest)" impossible.
Comment 4 Keith Rollin 2019-09-24 21:44:16 PDT
Huh. Going over email that's been sitting in my Inbox for a while, I reviewed a Coverity Scan that had been sent to me, and saw that it says exactly the same thing:

176         if (destCapacity > 0 && !dest) {
   CID 190890:  Control flow issues  (DEADCODE)
   Execution cannot reach this statement: "trimmedLength = static_cast...".
177             int32_t trimmedLength = static_cast<int32_t>(length);
Comment 5 Keith Rollin 2019-09-25 20:26:47 PDT
I've gone over the function in order to try to understand it. From what you've mentioned and from the Coverity error message, it seems like the if-block protected by the "if (destCapacity > 0 && !dest)" will never be executed. Since this is where the actual characters are being copied, it seems like this function never performed one of its primary functions, which is to extract a sub-string. Indeed, if the if-block *were* executed, the call to StringImpl::copyCharacters would fail since we'd be passing a NULL dest to it.

Examination of the code indicates to me that it's true that uTextLatin1Extract will in fact never be called. That function is part of a family of latin-1 related functions. That family of functions is only used in the context of the ICU function ubrk_setUText, which won't be extracting text. So it looks like uTextLatin1Extract was implemented in the name of completeness only.

Getting back to fixing the function, I think that that if-conditional should instead be "if (destCapacity > 0 && dest)". Or even just "if (dest)". I've made that change, along with adding an "if (dest)" in front of the the "dest[length] = 0" that triggered this whole task. And I took out the ASSERT that I'd added in order to quiet the static analyzer. With those changes, the code compiles and analyzes cleanly.

However, it's not clear if it actually works. It looks like it should work. But it looks like this function was never really used. And also never really tested. Some unit testing should probably be added for UTextProviderLatin1, UTextProviderUTF16, and UTextProvider. But since doing that could generate a whole series of follow-on tasks, I'd like that effort to be part of its own bug and leave this one to addressing the static-analyzer error.

Perhaps this whole function should just be replaced and implemented along the lines of its UTF16 analog? I'll just upload a patch that keeps the existing function largely intact, but could rip it out if people think that's the best approach.

static int32_t uTextUTF16ContextAwareExtract(UText*, int64_t, int64_t, UChar*, int32_t, UErrorCode* errorCode)
{
    // In the present context, this text provider is used only with ICU functions
    // that do not perform an extract operation.
    ASSERT_NOT_REACHED();
    *errorCode = U_UNSUPPORTED_ERROR;
    return 0;
}
Comment 6 Keith Rollin 2019-09-25 20:27:25 PDT
Created attachment 379617 [details]
Patch
Comment 7 Geoffrey Garen 2019-09-25 20:33:15 PDT
Comment on attachment 379617 [details]
Patch

r=me
Comment 8 WebKit Commit Bot 2019-09-25 23:41:22 PDT
Comment on attachment 379617 [details]
Patch

Clearing flags on attachment: 379617

Committed r250380: <https://trac.webkit.org/changeset/250380>
Comment 9 WebKit Commit Bot 2019-09-25 23:41:23 PDT
All reviewed patches have been landed.  Closing bug.