diff options
author | Yann Ylavic <ylavic@apache.org> | 2021-03-02 00:37:18 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2021-03-02 00:37:18 +0000 |
commit | 17f630750e9e5a40872d8c8c3a48622ed9244d53 (patch) | |
tree | a9497308b9bb36677fbb9827617ff237287d6c8c /test/testmmap.c | |
parent | 58126550800e0fd66790d216394e61772f329e6c (diff) | |
download | apr-17f630750e9e5a40872d8c8c3a48622ed9244d53.tar.gz |
Align apr_mmap()ing offset to a page boundary. PR 65158.
This is requirement for unix systems, and otherwise can cause failures or
undefined behaviour with some filesystems.
Add apr_mmap_t->poffset on unixes to track the offset to the previous page,
relative to the user requested/actual offset. This allows ->mm and ->size to
still point to the actual data, while munmap() still deletes the full range
from the start of the page.
Tests updated accordingly.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1887060 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testmmap.c')
-rw-r--r-- | test/testmmap.c | 96 |
1 files changed, 66 insertions, 30 deletions
diff --git a/test/testmmap.c b/test/testmmap.c index aeff1a66a..5ec0f69c2 100644 --- a/test/testmmap.c +++ b/test/testmmap.c @@ -35,18 +35,30 @@ static void not_implemented(abts_case *tc, void *data) #else -static char test_string[256]; /* read from the datafile */ +static apr_pool_t *ptest; +static char *thisfdata; /* read from the datafile */ static apr_mmap_t *themmap = NULL; static apr_file_t *thefile = NULL; static char *file1; static apr_finfo_t thisfinfo; static apr_size_t thisfsize; +static struct { + const char *filename; + apr_off_t offset; +} test_set[] = { + { "/data/mmap_datafile.txt", 0 }, + { "/data/mmap_large_datafile.txt", 65536 }, + { "/data/mmap_large_datafile.txt", 66650 }, /* not page aligned */ + { NULL, } +}; + static void create_filename(abts_case *tc, void *data) { + const char *filename = data; char *oldfileptr; - apr_filepath_get(&file1, 0, p); + apr_filepath_get(&file1, 0, ptest); #ifndef NETWARE #ifdef WIN32 ABTS_TRUE(tc, file1[1] == ':'); @@ -57,7 +69,7 @@ static void create_filename(abts_case *tc, void *data) ABTS_TRUE(tc, file1[strlen(file1) - 1] != '/'); oldfileptr = file1; - file1 = apr_pstrcat(p, file1,"/data/mmap_datafile.txt" ,NULL); + file1 = apr_pstrcat(ptest, file1, filename, NULL); ABTS_TRUE(tc, oldfileptr != file1); } @@ -67,25 +79,15 @@ static void test_file_close(abts_case *tc, void *data) rv = apr_file_close(thefile); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + thefile = NULL; } -static void read_expected_contents(abts_case *tc, void *data) -{ - apr_status_t rv; - apr_size_t nbytes = sizeof(test_string) - 1; - - rv = apr_file_read(thefile, test_string, &nbytes); - ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); - test_string[nbytes] = '\0'; - thisfsize = strlen(test_string); -} - static void test_file_open(abts_case *tc, void *data) { apr_status_t rv; rv = apr_file_open(&thefile, file1, APR_FOPEN_READ, - APR_FPROT_UREAD | APR_FPROT_GREAD, p); + APR_FPROT_UREAD | APR_FPROT_GREAD, ptest); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); ABTS_PTR_NOTNULL(tc, thefile); } @@ -96,28 +98,54 @@ static void test_get_filesize(abts_case *tc, void *data) rv = apr_file_info_get(&thisfinfo, APR_FINFO_NORM, thefile); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); - ABTS_ASSERT(tc, "File size mismatch", thisfsize == thisfinfo.size); + + thisfsize = thisfinfo.size; + thisfdata = apr_palloc(ptest, thisfsize + 1); + ABTS_PTR_NOTNULL(tc, thisfdata); +} + +static void read_expected_contents(abts_case *tc, void *data) +{ + apr_off_t *offset = data; + apr_size_t nbytes = 0; + apr_status_t rv; + + rv = apr_file_read_full(thefile, thisfdata, thisfsize, &nbytes); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + ABTS_ASSERT(tc, "File size mismatch", nbytes == thisfsize); + thisfdata[nbytes] = '\0'; + ABTS_ASSERT(tc, "File content size mismatch", + strlen(thisfdata) == thisfsize); + ABTS_ASSERT(tc, "File size too small", + (apr_size_t)*offset < thisfsize); + + /* From now, pretend that the file data and size don't include the + * offset, this avoids adding/substrating it to thisfdata/thisfsize + * all over the place in the next tests. + */ + thisfdata += *offset; + thisfsize -= *offset; } static void test_mmap_create(abts_case *tc, void *data) { + apr_off_t *offset = data; apr_status_t rv; - rv = apr_mmap_create(&themmap, thefile, 0, (apr_size_t) thisfinfo.size, - APR_MMAP_READ, p); + rv = apr_mmap_create(&themmap, thefile, *offset, thisfsize, + APR_MMAP_READ, ptest); ABTS_PTR_NOTNULL(tc, themmap); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } static void test_mmap_contents(abts_case *tc, void *data) { - ABTS_PTR_NOTNULL(tc, themmap); ABTS_PTR_NOTNULL(tc, themmap->mm); ABTS_SIZE_EQUAL(tc, thisfsize, themmap->size); /* Must use nEquals since the string is not guaranteed to be NULL terminated */ - ABTS_STR_NEQUAL(tc, themmap->mm, test_string, thisfsize); + ABTS_STR_NEQUAL(tc, themmap->mm, thisfdata, thisfsize); } static void test_mmap_delete(abts_case *tc, void *data) @@ -127,6 +155,7 @@ static void test_mmap_delete(abts_case *tc, void *data) ABTS_PTR_NOTNULL(tc, themmap); rv = apr_mmap_delete(themmap); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + themmap = NULL; } static void test_mmap_offset(abts_case *tc, void *data) @@ -139,8 +168,9 @@ static void test_mmap_offset(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* Must use nEquals since the string is not guaranteed to be NULL terminated */ - ABTS_STR_NEQUAL(tc, addr, test_string + 5, thisfsize-5); + ABTS_STR_NEQUAL(tc, addr, thisfdata + 5, thisfsize - 5); } + #endif abts_suite *testmmap(abts_suite *suite) @@ -148,15 +178,21 @@ abts_suite *testmmap(abts_suite *suite) suite = ADD_SUITE(suite) #if APR_HAS_MMAP - abts_run_test(suite, create_filename, NULL); - abts_run_test(suite, test_file_open, NULL); - abts_run_test(suite, read_expected_contents, NULL); - abts_run_test(suite, test_get_filesize, NULL); - abts_run_test(suite, test_mmap_create, NULL); - abts_run_test(suite, test_mmap_contents, NULL); - abts_run_test(suite, test_mmap_offset, NULL); - abts_run_test(suite, test_mmap_delete, NULL); - abts_run_test(suite, test_file_close, NULL); + apr_size_t i; + apr_pool_create(&ptest, p); + for (i = 0; test_set[i].filename; ++i) { + abts_run_test(suite, create_filename, (void *)test_set[i].filename); + abts_run_test(suite, test_file_open, NULL); + abts_run_test(suite, test_get_filesize, NULL); + abts_run_test(suite, read_expected_contents, &test_set[i].offset); + abts_run_test(suite, test_mmap_create, &test_set[i].offset); + abts_run_test(suite, test_mmap_contents, &test_set[i].offset); + abts_run_test(suite, test_mmap_offset, &test_set[i].offset); + abts_run_test(suite, test_mmap_delete, NULL); + abts_run_test(suite, test_file_close, NULL); + apr_pool_clear(ptest); + } + apr_pool_destroy(ptest); #else abts_run_test(suite, not_implemented, NULL); #endif |