lib: reject relative paths in n_d_{create,open}_verbose

There are many places in the notmuch code where the path is assumed to be absolute. If someone (TM) wants a project, one could remove these assumptions. In the mean time, prevent users from shooting themselves in the foot.

Update test suite mark tests for this error as no longer broken, and
also convert some tests that used relative paths for nonexistent
directories.
This commit is contained in:
David Bremner 2015-06-08 08:02:22 +02:00
parent b59ad1a9cc
commit 32fd74b7aa
5 changed files with 38 additions and 18 deletions

9
NEWS
View file

@ -1,3 +1,12 @@
Notmuch 0.21 (UNRELEASED)
=========================
Library
-------
The use of absolute paths is now enforced when calling notmuch_database_{open, create}
Notmuch 0.20.1 (2015-06-01)
===========================

View file

@ -659,6 +659,12 @@ notmuch_database_create_verbose (const char *path,
goto DONE;
}
if (path[0] != '/') {
message = strdup ("Error: Database path must be absolute.\n");
status = NOTMUCH_STATUS_PATH_ERROR;
goto DONE;
}
err = stat (path, &st);
if (err) {
IGNORE_RESULT (asprintf (&message, "Error: Cannot create database at %s: %s.\n",
@ -849,6 +855,12 @@ notmuch_database_open_verbose (const char *path,
goto DONE;
}
if (path[0] != '/') {
message = strdup ("Error: Database path must be absolute.\n");
status = NOTMUCH_STATUS_PATH_ERROR;
goto DONE;
}
if (! (notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch"))) {
message = strdup ("Out of memory\n");
status = NOTMUCH_STATUS_OUT_OF_MEMORY;

View file

@ -11,16 +11,17 @@ test_description='exception symbol hiding'
. ./test-lib.sh
run_test(){
result=$(LD_LIBRARY_PATH="$TEST_DIRECTORY/../lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" $TEST_DIRECTORY/symbol-test 2>&1)
}
test_begin_subtest 'running test' run_test
mkdir -p ${PWD}/fakedb/.notmuch
( LD_LIBRARY_PATH="$TEST_DIRECTORY/../lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \
$TEST_DIRECTORY/symbol-test ${PWD}/fakedb ${PWD}/nonexistent \
2>&1 | sed "s,${PWD},CWD,g") > OUTPUT
output="A Xapian exception occurred opening database: Couldn't stat 'fakedb/.notmuch/xapian'
caught No chert database found at path \`./nonexistent'"
mkdir -p fakedb/.notmuch
test_expect_success 'running test' run_test
cat <<EOF > EXPECTED
A Xapian exception occurred opening database: Couldn't stat 'CWD/fakedb/.notmuch/xapian'
caught No chert database found at path \`CWD/nonexistent'
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest 'checking output'
test_expect_equal "$result" "$output"

View file

@ -36,7 +36,6 @@ EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "Open relative path"
test_subtest_known_broken
test_C <<'EOF'
#include <stdio.h>
#include <notmuch.h>
@ -55,7 +54,6 @@ EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "Create database in relative path"
test_subtest_known_broken
test_C <<'EOF'
#include <stdio.h>
#include <notmuch.h>
@ -108,21 +106,21 @@ Error: Cannot create a database for a NULL path.
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "Create database in non-existant directory"
test_C <<'EOF'
test_begin_subtest "Create database in nonexistent directory"
test_C ${PWD}/nonexistent/foo<<'EOF'
#include <stdio.h>
#include <notmuch.h>
int main (int argc, char** argv)
{
notmuch_database_t *db;
notmuch_status_t stat;
stat = notmuch_database_create ("./nonexistent/foo", &db);
stat = notmuch_database_create (argv[1], &db);
}
EOF
cat <<'EOF' >EXPECTED
== stdout ==
== stderr ==
Error: Cannot create database at ./nonexistent/foo: No such file or directory.
Error: Cannot create database at CWD/nonexistent/foo: No such file or directory.
EOF
test_expect_equal_file EXPECTED OUTPUT

View file

@ -4,18 +4,18 @@
#include <notmuch.h>
int main() {
int main(int argc, char** argv) {
notmuch_database_t *notmuch;
char *message = NULL;
if (notmuch_database_open_verbose ("fakedb", NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch, &message))
if (notmuch_database_open_verbose (argv[1], NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch, &message))
if (message) {
fputs (message, stderr);
free (message);
}
try {
(void) new Xapian::WritableDatabase("./nonexistent", Xapian::DB_OPEN);
(void) new Xapian::WritableDatabase(argv[2], Xapian::DB_OPEN);
} catch (const Xapian::Error &error) {
printf("caught %s\n", error.get_msg().c_str());
return 0;