[CXX-1191] Backport mongocxx::uri::database() segfaults if no database specified in URL Created: 11/Jan/17  Updated: 11/Aug/17  Resolved: 16/Jun/17

Status: Closed
Project: C++ Driver
Component/s: Implementation
Affects Version/s: None
Fix Version/s: 3.1.2

Type: Bug Priority: Major - P3
Reporter: J Rassi Assignee: Samuel Rossi (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Backports
backports CXX-1187 mongocxx::uri::database() segfaults i... Closed

 Description   

Backport of CXX-1187 to 3.1.2.

Reproducer:

mongocxx::uri uri{mongocxx::uri::k_default_uri};
std::cout << uri.database() << std::endl;

Expected:

  • Should print out the empty string. Or, well, there's some room for debase here. It would also be ok if it asserted, if there were some sort of "has_database()" method so I can check whether a database is present.

Actual:

  • On my Mac (OS X Sierra), crashes with a segmentation fault. On my Linux box (Ubuntu 16.04), dumps some scary-looking memory debug information and exits.

Analysis:

The root of the problem appears to be in the deceptively-simple-looking "mongocxx::uri::database()":

std::string uri::database() const {
    return libmongoc::uri_get_database(_impl->uri_t);
}

libmongoc::uri_get_database() returns a char*. Because we are returning a std::string, C++ performs an implicit cast.

If no database was specified in the URI, uri_get_database() returns NULL, not (for example) "". I think this is an entirely reasonable C API. However, the implicit std::string(const char*) constructor requires/assumes that the char* point to a valid string. When passed a NULL pointer, it dereferences that pointer and causes a segfault.

A trivial solution would be to add a helper that handles NULL somehow. For example:

std::string safe_string(const char* ch)
{
    if (!ch) { return ""; }
    return std::string(ch);
}
std::string uri::database() const {
    return safe_string(libmongoc::uri_get_database(_impl->uri_t));
}

But there are a bunch of design decisions here. Also, just glancing at the code in this file, I suspect that some other accessors on this class may be affected by the same issue.



 Comments   
Comment by Samuel Rossi (Inactive) [ 16/Jun/17 ]

Author:

{u'username': u'saghm', u'name': u'Saghm Rossi', u'email': u'saghmrossi@gmail.com'}

Message: CXX-1187 Minor style/lint fixes to uri.cpp and test/uri.cpp
Branch: bugfix/3.1.x
https://github.com/mongodb/mongo-cxx-driver/commit/3ba0d6ffee2d15574402684e93fea5434fdddbe0

Generated at Wed Feb 07 22:01:42 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.