Closed
Bug 1381080
Opened 7 years ago
Closed 7 years ago
add assertions about string class null-termination invariants
Categories
(Core :: XPCOM, enhancement)
Core
XPCOM
Tracking
()
RESOLVED
FIXED
mozilla56
Tracking | Status | |
---|---|---|
firefox56 | --- | fixed |
People
(Reporter: dbaron, Assigned: dbaron)
References
(Blocks 1 open bug)
Details
Attachments
(7 files, 1 obsolete file)
(deleted),
patch
|
erahm
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
erahm
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
erahm
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
Details | Diff | Splinter Review | |
(deleted),
patch
|
Details | Diff | Splinter Review | |
(deleted),
patch
|
erahm
:
review+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
erahm
:
review+
|
Details | Diff | Splinter Review |
I have some patches to add some assertions to the string classes about null-termination invariants. More details coming in the patch descriptions...
Assignee | ||
Comment 1•7 years ago
|
||
Assignee | ||
Comment 2•7 years ago
|
||
This is needed for patch 4.
MozReview-Commit-ID: 5ikQFIL9O0i
Attachment #8886693 -
Flags: review?(erahm)
Assignee | ||
Comment 3•7 years ago
|
||
This is needed for patch 4.
MozReview-Commit-ID: 7xKQv37cy5k
Attachment #8886694 -
Flags: review?(erahm)
Assignee | ||
Comment 4•7 years ago
|
||
This is needed for patch 4.
MozReview-Commit-ID: 4BFlTtQdtoN
Attachment #8886695 -
Flags: review?(erahm)
Assignee | ||
Comment 5•7 years ago
|
||
I actually couldn't figure out a way to trigger this assertion with the
current string code without doing invalid casts, but there are things we
may want to add to the string code in the future that might risk hitting
this (e.g., move constructors, promoting various rebind methods to
nsA[C]String), so I think it's worth asserting.
MozReview-Commit-ID: 4R0dYuTfrFW
Attachment #8886696 -
Flags: review?(erahm)
Assignee | ||
Comment 6•7 years ago
|
||
This avoids triggering the assertions added in patch 6.
MozReview-Commit-ID: 9000zY0FDId
Assignee | ||
Comment 7•7 years ago
|
||
While it would be nice to assert this in AssertValid() (added in the
previous patch), this is difficult because of what MutatePrep does:
https://searchfox.org/mozilla-central/rev/cbd628b085ac809bf5a536109e6288aa91cbdff0/xpcom/string/nsTSubstring.cpp#152,165,177-178
MozReview-Commit-ID: 12sQLHtJ4xc
Assignee | ||
Comment 8•7 years ago
|
||
I decided I don't actually want to land the last two patches, given how awkward it is to use the string API to do what the one caller that needed fixing wants to do. I think we should:
* first, make that easier, and then
* second, try to do the stronger assertions that I mention in patch 6 (i.e., in the same place as the code in patch 4)
Comment 9•7 years ago
|
||
Comment on attachment 8886693 [details] [diff] [review]
patch 1 - Add ClassFlags::NULL_TERMINATED to strings that require null-termination
Review of attachment 8886693 [details] [diff] [review]:
-----------------------------------------------------------------
::: xpcom/string/nsTString.h
@@ +466,5 @@
> // allow subclasses to initialize fields directly
> nsTString_CharT(char_type* aData, size_type aLength, DataFlags aDataFlags,
> ClassFlags aClassFlags)
> + : substring_type(aData, aLength, aDataFlags,
> + aClassFlags | ClassFlags::NULL_TERMINATED)
This one seems a little sketchy, it would be nice if there were a way to make sure we don't goof up and make a subclass that expects to *not* be null terminated.
I'd almost prefer pushing the flag to the subclass and asserting they set NULL_TERMINATED, but I can see how that would require a lot more changes.
Attachment #8886693 -
Flags: review?(erahm) → review+
Updated•7 years ago
|
Attachment #8886694 -
Flags: review?(erahm) → review+
Comment 10•7 years ago
|
||
Comment on attachment 8886695 [details] [diff] [review]
patch 3 - Encapsulate setting mData/mLength/mDataFlags in a new method
Review of attachment 8886695 [details] [diff] [review]:
-----------------------------------------------------------------
::: xpcom/string/nsTDependentString.cpp
@@ +27,5 @@
> startPos = strLength;
> }
>
> + char_type* newData =
> + const_cast<char_type*>(static_cast<const char_type*>(str.Data())) + startPos;
Just curious, why do we need the static_cast? char16ptr_t weirdness? It would be nice to drop it if we don't need it anymore.
Attachment #8886695 -
Flags: review?(erahm) → review+
Assignee | ||
Comment 11•7 years ago
|
||
(In reply to Eric Rahm [:erahm] (please no mozreview requests) from comment #9)
> This one seems a little sketchy, it would be nice if there were a way to
> make sure we don't goof up and make a subclass that expects to *not* be null
> terminated.
Any subclass that isn't null-terminated should derive from nsTSubstring rather than nsTString. That's the key static type distinction between the two.
(In reply to Eric Rahm [:erahm] (please no mozreview requests) from comment #10)
> Just curious, why do we need the static_cast? char16ptr_t weirdness? It
> would be nice to drop it if we don't need it anymore.
I noticed that too, and concluded from https://searchfox.org/mozilla-central/rev/cbd628b085ac809bf5a536109e6288aa91cbdff0/mfbt/Char16.h#20-21 that we probably still needed it.
Comment 12•7 years ago
|
||
Comment on attachment 8886696 [details] [diff] [review]
patch 4 - Assert that strings whose static type requires a null-terminated buffer aren't assign a non-null-terminated buffer
Review of attachment 8886696 [details] [diff] [review]:
-----------------------------------------------------------------
This seems okay, a few notes below.
::: xpcom/string/nsTSubstring.h
@@ -304,5 @@
>
> protected:
> nsTStringRepr_CharT() = delete; // Never instantiate directly
>
> - constexpr
This could still be constexpr in release builds right?
@@ +1093,5 @@
> {
> mData = char_traits::sEmptyBuffer;
> mLength = 0;
> mDataFlags = DataFlags::TERMINATED;
> + AssertValid();
Given the assertion we know this is always true right?
Attachment #8886696 -
Flags: review?(erahm) → review+
Assignee | ||
Comment 13•7 years ago
|
||
(In reply to Eric Rahm [:erahm] (please no mozreview requests) from comment #12)
> > - constexpr
>
> This could still be constexpr in release builds right?
I guess it could. Is there a reason it's valuable for it to be constexpr?
> > mData = char_traits::sEmptyBuffer;
> > mLength = 0;
> > mDataFlags = DataFlags::TERMINATED;
> > + AssertValid();
>
> Given the assertion we know this is always true right?
Yeah, but I decided I wanted it there anyway for future additions to AssertValid().
Comment 14•7 years ago
|
||
(In reply to David Baron :dbaron: ⌚️UTC-7 from comment #11)
> (In reply to Eric Rahm [:erahm] (please no mozreview requests) from comment
> #9)
> > This one seems a little sketchy, it would be nice if there were a way to
> > make sure we don't goof up and make a subclass that expects to *not* be null
> > terminated.
>
> Any subclass that isn't null-terminated should derive from nsTSubstring
> rather than nsTString. That's the key static type distinction between the
> two.
Yeah I understand, but my thought was it would be nice if we could statically enforce / assert that fact to avoid future issues. I guess that can just be "you need to understand this stuff" and code review from string person should catch it.
> (In reply to Eric Rahm [:erahm] (please no mozreview requests) from comment
> #10)
> > Just curious, why do we need the static_cast? char16ptr_t weirdness? It
> > would be nice to drop it if we don't need it anymore.
>
> I noticed that too, and concluded from
> https://searchfox.org/mozilla-central/rev/
> cbd628b085ac809bf5a536109e6288aa91cbdff0/mfbt/Char16.h#20-21 that we
> probably still needed it.
I was thinking the implicit conversion to |const char16_t*| [1] might handle it for us, but maybe not inside a const_cast?
[1] https://searchfox.org/mozilla-central/rev/cbd628b085ac809bf5a536109e6288aa91cbdff0/mfbt/Char16.h#51-54
Comment 15•7 years ago
|
||
(In reply to David Baron :dbaron: ⌚️UTC-7 from comment #13)
> (In reply to Eric Rahm [:erahm] (please no mozreview requests) from comment
> #12)
> > > - constexpr
> >
> > This could still be constexpr in release builds right?
>
> I guess it could. Is there a reason it's valuable for it to be constexpr?
David, you added a constexpr ctor in your nsTStringRepr class patch [1], is their a compelling reason to keep it constexpr? My guess is yes because (vaguely) it gives the compiler a chance to do some optimizations, but it would be nice to hear your reasoning.
[1] https://reviewboard.mozilla.org/r/119210/diff/3#index_header
Flags: needinfo?(dmajor)
Comment 16•7 years ago
|
||
(In reply to Eric Rahm [:erahm] (please no mozreview requests) from comment #15)
> David, you added a constexpr ctor in your nsTStringRepr class patch [1], is
> their a compelling reason to keep it constexpr? My guess is yes because
> (vaguely) it gives the compiler a chance to do some optimizations, but it
> would be nice to hear your reasoning.
>
> [1] https://reviewboard.mozilla.org/r/119210/diff/3#index_header
My first thought is that I must have added it to be extra-super-duper sure that global nsTLiteralStrings can be set up as just plain static data, without having to run constructors. But apparently I didn't add a constexpr constructor on nsTLiteralString itself, so I guess it's not a concern.
My second guess would be that I added it as a safety net so that we error out if you add a new field and accidentally omit it from the ctor, since constexpr requires all members to be initialized.
Flags: needinfo?(dmajor)
Comment 17•7 years ago
|
||
...and/or possibly to reinforce the fact that nsTStringRepr is (was) just a dumb POD with no logic.
Assignee | ||
Comment 18•7 years ago
|
||
OK, maybe it's best to move the AssertValid() into nsTString (and just skip adding an equivalent to nsTLiteralString), and post a separate patch to add the constexpr to the nsTLiteralString constructor?
Assignee | ||
Comment 19•7 years ago
|
||
I actually couldn't figure out a way to trigger this assertion with the
current string code without doing invalid casts, but there are things we
may want to add to the string code in the future that might risk hitting
this (e.g., move constructors, promoting various rebind methods to
nsA[C]String), so I think it's worth asserting.
MozReview-Commit-ID: 4R0dYuTfrFW
Attachment #8887721 -
Flags: review?(erahm)
Assignee | ||
Updated•7 years ago
|
Attachment #8886696 -
Attachment is obsolete: true
Assignee | ||
Comment 20•7 years ago
|
||
Assignee | ||
Comment 21•7 years ago
|
||
MozReview-Commit-ID: 5ASqQAGBqq
Attachment #8887722 -
Flags: review?(erahm)
Updated•7 years ago
|
Attachment #8887721 -
Flags: review?(erahm) → review+
Updated•7 years ago
|
Attachment #8887722 -
Flags: review?(erahm) → review+
Assignee | ||
Comment 22•7 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/79bc740e42aaeb256202eef44335a563594a7b04
Bug 1381080 patch 1 - Add ClassFlags::NULL_TERMINATED to strings that require null-termination. r=erahm
https://hg.mozilla.org/integration/mozilla-inbound/rev/e5e88978e73540cdd60f7a0374ac74b8fcfe0925
Bug 1381080 patch 2 - Encapsulate setting to empty buffer in a new method. r=erahm
https://hg.mozilla.org/integration/mozilla-inbound/rev/235ac09dfdb2412295ac98834fb111e9198b0474
Bug 1381080 patch 3 - Encapsulate setting mData/mLength/mDataFlags in a new method. r=erahm
https://hg.mozilla.org/integration/mozilla-inbound/rev/9b76213c99cfcb05a53d381edd272cbc29e6fadf
Bug 1381080 patch 4 - Assert that strings whose static type requires a null-terminated buffer aren't assign a non-null-terminated buffer. r=erahm
https://hg.mozilla.org/integration/mozilla-inbound/rev/5a663e876c3c2d76703368581b033f28495c10e1
Bug 1381080 patch 7 - Mark nsLiteral[C]String constructor as constexpr. r=erahm
Comment 23•7 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/79bc740e42aa
https://hg.mozilla.org/mozilla-central/rev/e5e88978e735
https://hg.mozilla.org/mozilla-central/rev/235ac09dfdb2
https://hg.mozilla.org/mozilla-central/rev/9b76213c99cf
https://hg.mozilla.org/mozilla-central/rev/5a663e876c3c
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
status-firefox56:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
Updated•7 years ago
|
status-firefox57:
affected → ---
Updated•7 years ago
|
Blocks: StringCleaning
Updated•4 years ago
|
Component: String → XPCOM
You need to log in
before you can comment on or make changes to this bug.
Description
•