php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #74883 SQLite3::__construct() produces "out of memory" exception with invalid flags
Submitted: 2017-07-08 21:00 UTC Modified: 2017-07-17 13:55 UTC
From: jeroen at treurniet dot us Assigned: danack
Status: Closed Package: SQLite related
PHP Version: 7.1.7 OS: Windows
Private report: No CVE-ID:
 [2017-07-08 21:00 UTC] jeroen at treurniet dot us
Description:
------------
When opening a SQLite3 database with both the SQLITE3_OPEN_READONLY and SQLITE3_OPEN_CREATE flags, an exception thrown which reads "Unable to open database: out of memory".

While it is understandable that it doesn't make sense to combine the two flags (since creating a new database would require writing, and opening an empty database that cannot be written to is probably not very helpful), the "out of memory" error is confusing, and does not seem like an accurate description of the problem. Especially since the documentation for neither SQLite3::__construct() and SQLite3::open() hints to this, I was personally stuck for some time figuring out why it was telling me it was out of memory.

This behavior occurs regardless of whether or not the specified database file actually exists/is readable.

I propose that when either of these functions is called with SQLITE3_OPEN_READONLY, they should either silently ignore the SQLITE3_OPEN_CREATE flag if it is specified, or produce an E_NOTICE with a more helpful message, rather than throwing a fatal error with an unhelpful description ("out of memory").

Test script:
---------------
$db = new SQLite3( "my_database.db", SQLITE3_OPEN_READONLY | SQLITE3_OPEN_CREATE );

Expected result:
----------------
Either silently ignore the SQLITE3_OPEN_CREATE flag, or throw an E_NOTICE rather than an exception.

Actual result:
--------------
Fatal error: Uncaught Exception: Unable to open database: out of memory in ...

Patches

ignore-open-create-with-open-readonly (last revision 2017-07-08 21:42 UTC) by jeroen at treurniet dot us)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-07-08 21:57 UTC] ab@php.net
Thanks for the report. As for me, the suggested solution doesn't sound optimal. It is application dependent, so why should be one flag removed in favor of another one? Another script might need it in exactly opposite way. IMO it is merely about improving the error check, not more. SQLite should be able to detect such cases.

Thanks.
 [2017-07-08 23:38 UTC] ab@php.net
Automatic comment on behalf of ab
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b5338c0b7d145d9b5b5abcb9d695691ca5d6e418
Log: Fixed bug #74883 SQLite3::__construct() produces "out of memory" exception with invalid flags
 [2017-07-08 23:38 UTC] ab@php.net
-Status: Open +Status: Closed
 [2017-07-09 16:32 UTC] danack@php.net
The error message originate in the underlying SQLite library. I've sent a bug report to the SQLite mailing list, to see if the message can be improved.


> they should either silently ignore

No. Programs shouldn't silently discard data.


> rather than throwing a fatal error with an unhelpful description ("out of memory").

It doesn't throw an 'error'; it throws an Exception, and your code code should be catching exceptions both at the location where you're calling new SQLite3() - to catch expected error conditions, such as the database file not being open-able, and also at the top level of the application, to log all 'unexpected' exceptions that you weren't aware that could occur..

> produce an E_NOTICE with a more helpful message

No. The error message should be better, but E_NOTICES are not a good way to handle failed constructors. All constructors must either succeed or throw an exception. This was decided by RFC recently: https://wiki.php.net/rfc/internal_constructor_behaviour
 [2017-07-17 13:55 UTC] danack@php.net
-Assigned To: +Assigned To: danack
 [2017-07-17 13:55 UTC] danack@php.net
After some investigation, this problem does like in the underlying SQLite library, that isn't present when compiled with an up-to-date version.

I'll open a separate issue to update SQLite.
 [2017-08-05 14:23 UTC] 170805 at 0x440x48 dot com
The fix applied in this thread makes PHP7.1.8 use sqlite3_errstr. This symbol is not available in sqlite version 3.6.20, which is system default on RHEL6.

Remi's repo has a patch for this his the latest SRPM:
https://rpms.remirepo.net/SRPMS/repoview/php71-php.html
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sat Aug 19 14:01:35 2017 UTC