Closed Bug 1534124 Opened 5 years ago Closed 5 years ago

Make nsMsgImapLineDownloadCache::SpaceAvailable() more robust

Categories

(MailNews Core :: Networking: IMAP, defect)

x86
All
defect
Not set
critical

Tracking

(Not tracked)

RESOLVED FIXED
Thunderbird 67.0

People

(Reporter: jorgk-bmo, Assigned: jorgk-bmo)

References

Details

Attachments

(1 file, 1 obsolete file)

+++ This bug was initially created as a clone of Bug #1534119 +++

This is simply returning the difference of two unsigned ints which can be detrimental.

Attached patch 1534124-SpaceAvailable.patch (obsolete) — Splinter Review
Assignee: nobody → jorgk
Status: NEW → ASSIGNED
Attachment #9049807 - Flags: review?(mkmelin+mozilla)
See Also: → 1534119
Comment on attachment 9049807 [details] [diff] [review]
1534124-SpaceAvailable.patch

Review of attachment 9049807 [details] [diff] [review]:
-----------------------------------------------------------------

I'm think this is not really optimal.
The assert could happen for a correct operation, so we shouldn't use assert for that.

Looks like kDownLoadCacheSize should always be unsigned, and handled as such.
Attachment #9049807 - Flags: review?(mkmelin+mozilla) → review-

What? MOZ_ASSERT() only runs in debug so developers with a debug build can notice it.

If it happens for a "correct operation", which it shouldn't, I return 0, instead of returning -55 which is a huge number if taken unsigned.

I don't understand the last sentence, kDownLoadCacheSize is simply 16000:
https://searchfox.org/comm-central/rev/1e408f63a08ea6ba10bcabd906834edf9de4a7bb/mailnews/imap/src/nsImapProtocol.h#57

Attachment #9049807 - Flags: review- → review?(benc)

Assert is to notice programmatically wrong logic. In this the logic is correct I think, and could trigger with the suitable data amounts. That is, not a logic error.

I'm not sure about the syntax but perhaps "#define kDownLoadCacheSize 16000u" would give you what you want. That GrowBuffer uses a signed int looks wrong since it's cooperating with a cache that is unsigned.

Right, assert is to detect wrong logic, so a pointer to after the end of a buffer seems to be as wrong as it gets.

That combined with then returning "-55 bytes available in the buffer" as a humongous amount being available is a total disaster. I don't need 16000u since I will only subtract a number less or equal to 16000.

This cleans up a bit more signed/unsigned confusion but won't make a difference.

Attachment #9049807 - Attachment is obsolete: true
Attachment #9049807 - Flags: review?(benc)
Attachment #9049980 - Flags: review?(mkmelin+mozilla)
Comment on attachment 9049980 [details] [diff] [review]
1534124-SpaceAvailable.patch (v2)

Let's have our backend specialist have a look ;-)
Attachment #9049980 - Flags: review?(benc)
Comment on attachment 9049980 [details] [diff] [review]
1534124-SpaceAvailable.patch (v2)

Review of attachment 9049980 [details] [diff] [review]:
-----------------------------------------------------------------

::: mailnews/imap/src/nsImapProtocol.cpp
@@ +224,5 @@
>  uint32_t nsMsgImapLineDownloadCache::SpaceAvailable()
>  {
> +  MOZ_ASSERT(kDownLoadCacheSize >= m_bufferPos);
> +  if (kDownLoadCacheSize <= m_bufferPos)
> +    return 0;

with the change to unsigned this shouldn't be necessary. The assert is slightly more correct in the new situation, but it's now an odd place to have it, so I'd rather skip it.
Attachment #9049980 - Flags: review?(mkmelin+mozilla)

I still don't understand. You can have two unsigned ints, like 16000u and 17000u and 16000u - 17000u surprisingly is a very large positive number. The original code just blindly subtracts two (now) unsigned numbers. What am I missing? How would you protect against a "bad" subtraction?

Ah I guess it's correct then.

Comment on attachment 9049980 [details] [diff] [review]
1534124-SpaceAvailable.patch (v2)

Review of attachment 9049980 [details] [diff] [review]:
-----------------------------------------------------------------

::: mailnews/imap/src/nsImapProtocol.cpp
@@ +224,5 @@
>  uint32_t nsMsgImapLineDownloadCache::SpaceAvailable()
>  {
> +  MOZ_ASSERT(kDownLoadCacheSize >= m_bufferPos);
> +  if (kDownLoadCacheSize <= m_bufferPos)
> +    return 0;

I think the assert is valid. The assert will not trigger because of malformed input data - it'll trigger because some code has screwed up the buffer and left it in an invalid state.

I'd suggest that `m_bufferSize` would be better to use than `kDownLoadCacheSize`, as it would remove the reliance on prior knowledge about calling `GrowBuffer(kDownloadCacheSize)`.

Is it a good idea returning 0 when things screw up in release builds? If a problem actually occurs, might this just mask it? I'd rather it just crashed hard then and there (and letting it return a negative number would probably do that nicely)

That said, I'm happy to r+ it as is. If the buffer does get into an odd state, the assert will pick it up in debugs build, and the release-build behaviour is going to be anomalous if that happens, safety-check or not.
Attachment #9049980 - Flags: review?(benc) → review+

Ahh, yes, you're right - m_bufferSize is the one from nsByteArray!

Well, sadly that doesn't compile since nsMsgImapLineDownloadCache can't access that member of nsMsgLineStreamBuffer even if you make if public :-(

Pushed by mozilla@jorgk.com:
https://hg.mozilla.org/comm-central/rev/6117debc9c8a
Be more conservative in nsMsgImapLineDownloadCache::SpaceAvailable(). r=mkmelin,benc DONTBUILD

Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED

(In reply to Ben Campbell from comment #11)

Is it a good idea returning 0 when things screw up in release builds? If a
problem actually occurs, might this just mask it? I'd rather it just crashed
hard then and there (and letting it return a negative number would probably
do that nicely)

Well, there is no "negative" number, the negative number will be returned as a large positive number, so the code will happily overwrite the buffer and crash elsewhere in an uncontrolled fashion. The only option we have it to change the MOZ_ASSERT() to a MOZ_CRASH() or MOZ_RELEASE_ASSERT() but then the user crashes. It might be better to keep limping along with a truncated message. Hard to tell.

Target Milestone: --- → Thunderbird 67.0
See Also: → 1737293
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: