[CXX-554] mongo::Date_t::toTimeT() crash Created: 11/Mar/15  Updated: 02/Apr/15  Resolved: 11/Mar/15

Status: Closed
Project: C++ Driver
Component/s: None
Affects Version/s: legacy-0.0-26compat-2.6.6
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Christian Wyss Assignee: Adam Midvidy
Resolution: Done Votes: 0
Labels: legacy-cxx
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Read a date which is defined as ISODate("0001-01-01T00:00:00Z") from mongodb into a Date_t, then calling toTimeT() crashes, probably because time_t cannot represent dates before 1970 and the conversion doesn't check this.
No exception thrown neither - try/catch block could not handle the case.

(gdb) bt
#0 0x00007f92545b35db in raise () from /lib64/libpthread.so.0
#1 0x00000000006b2c47 in mongo::mongo_breakpoint() ()
#2 0x00000000006aca17 in mongo::verifyFailed(char const*, char const*, unsigned int) ()
#3 0x00000000006bedf4 in mongo::Date_t::toTimeT() const ()



 Comments   
Comment by Christian Wyss [ 02/Apr/15 ]

Hello Adam

I think you must be misunderstanding.
We have ISODate("0001-01-01T00:00:00Z") stored in the MongoDB. This works fine.
We then read this field - by a query or whatever - into a Date_t structure via C++ code. Works fine, too.

BUT: when I now call toTimeT() on that structure: segfault.

It's clear to me WHY this happens: this date cannot be represented as a time_t, which - in most of today's systems - has been replaced by an unsigned 64 bit integer - but still starts 1970, so year 0000 is out of the allowed range.

But this should at least be checked and signalled by an exception - instead it segfaults, what I consider a bug.

Comment by Adam Midvidy [ 11/Mar/15 ]

Hey Christian,

Date_t is represented internally as a 64-bit unsigned integer - so when a Date_t is created from a negative pre-1970 value, it is converted to a (large) positive value. There is currently an assert in the toTimeT() call to check that the value of the Date_t can fit in a time_t, which is a 32 bit signed integer on many systems. This is an unfriendly interface, but we have decided to be very conservative about making changes to the 26compat branch.

As a workaround, check the result of the isFormattable() method on Date_t before calling toTimeT().

There is a ticket, SERVER-8573, to fix this issue in the server sources. When it is resolved, the fix may be backported to the legacy branch, but likely not 26compat.

Best,
Adam

Generated at Wed Feb 07 21:59:33 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.