Fixed issues with resolving paths.

Added source directory to includes.
Added unit tests for resolving paths.
Fixed compilation issues with test code.
This commit is contained in:
Nathan Moinvaziri 2018-06-19 09:44:06 -07:00
parent dd808239dd
commit 957f2e9976
3 changed files with 134 additions and 44 deletions

View File

@ -71,6 +71,8 @@ set(MINIZIP_PUBLIC_HEADERS
mz_strm_split.h
mz_zip.h)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
if(WIN32)
list(APPEND MINIZIP_SRC "mz_os_win32.c" "mz_strm_win32.c")
list(APPEND MINIZIP_PUBLIC_HEADERS "mz_os_win32.h" "mz_strm_win32.h")

101
mz_os.c
View File

@ -101,62 +101,85 @@ int32_t mz_path_combine(char *path, const char *join, int32_t max_path)
int32_t mz_path_resolve(const char *path, char *output, int32_t max_output)
{
const char *source = path;
const char *check = output;
char *target = output;
int16_t slash_count = 0;
if (max_output <= 0)
return MZ_PARAM_ERROR;
while (*source != 0 && max_output > 1)
{
// Skip double paths
if ((source[0] == '\\' || source[0] == '/') &&
(source[1] == '\\' || source[1] == '/'))
check = source;
if ((*check == '\\') || (*check == '/'))
check += 1;
if ((source == path) || (check != source) || (*target == 0))
{
source += 1;
continue;
}
// Skip current directory .\ or ./
if ((source[0] == '.') &&
(source[1] == 0 || source[1] == '\\' || source[1] == '/'))
{
if (source[1] == 0)
// Skip double paths
if ((*check == '\\') || (*check == '/'))
{
source += 1;
break;
continue;
}
source += 2;
continue;
}
// Go back for parent directory ..\ or ../
if ((source[0] == '.') && (source[1] != 0 && source[1] == '.') &&
(source[2] == 0 || source[2] == '\\' || source[2] == '/'))
{
slash_count = 0;
while (target >= output)
if ((*check != 0) && (*check == '.'))
{
if (*target == '\\' || *target == '/')
check += 1;
// Remove current directory . if at end of stirng
if ((*check == 0) && (source != path))
{
slash_count += 1;
if (slash_count == 2)
break;
// Copy last slash
*target = *source;
target += 1;
max_output -= 1;
source += (check - source);
continue;
}
if (target == output)
break;
// Remove current directory . if not at end of stirng
if ((*check == 0) || (*check == '\\' || *check == '/'))
{
// Only proceed if .\ is not entire string
if (check[1] != 0 || (path != source))
{
source += (check - source);
continue;
}
}
target -= 1;
max_output += 1;
// Go to parent directory ..
if ((*check != 0) || (*check == '.'))
{
check += 1;
if ((*check == 0) || (*check == '\\' || *check == '/'))
{
source += (check - source);
// Search backwards for previous slash
if (target != output)
{
target -= 1;
do
{
if ((*target == '\\') || (*target == '/'))
break;
target -= 1;
max_output += 1;
}
while (target > output);
}
if ((target == output) && (*source != 0))
source += 1;
if ((*target == '\\' || *target == '/') && (*source == 0))
target += 1;
*target = 0;
continue;
}
}
}
if (source[2] == 0)
target += 1;
if (target == output)
source += 1;
source += 2;
*target = 0;
continue;
}
*target = *source;

View File

@ -9,14 +9,72 @@
#include "mz_os.h"
#include "mz_strm.h"
#include "mz_strm_mem.h"
#ifdef HAVE_BZIP
#include "mz_strm_bzip.h"
#include "mz_strm_crypt.h"
#endif
#ifdef HAVE_PKCRYPT
#include "mz_strm_pkcrypt.h"
#endif
#ifdef HAVE_AES
#include "mz_strm_aes.h"
#endif
#ifdef HAVE_ZLIB
#include "mz_strm_zlib.h"
#endif
#include "mz_zip.h"
/***************************************************************************/
void test_path_resolve(void)
{
char output[256];
int32_t ok = 0;
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\.", output, sizeof(output));
ok = (strcmp(output, "c:\\test\\") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\.\\", output, sizeof(output));
ok = (strcmp(output, "c:\\test\\") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\..", output, sizeof(output));
ok = (strcmp(output, "c:\\") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\..\\", output, sizeof(output));
ok = (strcmp(output, "c:\\") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\.\\..", output, sizeof(output));
ok = (strcmp(output, "c:\\") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\.\\\\..", output, sizeof(output));
ok = (strcmp(output, "c:\\") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve(".", output, sizeof(output));
ok = (strcmp(output, ".") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve(".\\", output, sizeof(output));
ok = (strcmp(output, "") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("..", output, sizeof(output));
ok = (strcmp(output, "") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("..\\", output, sizeof(output));
ok = (strcmp(output, "") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\123\\.\\abc.txt", output, sizeof(output));
ok = (strcmp(output, "c:\\test\\123\\abc.txt") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\123\\..\\abc.txt", output, sizeof(output));
ok = (strcmp(output, "c:\\test\\abc.txt") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\123\\..\\..\\abc.txt", output, sizeof(output));
ok = (strcmp(output, "c:\\abc.txt") == 0);
memset(output, 'z', sizeof(output));
mz_path_resolve("c:\\test\\123\\..\\..\\..\\abc.txt", output, sizeof(output));
ok = (strcmp(output, "abc.txt") == 0);
memset(output, 'z', sizeof(output));
}
void test_encrypt(char *method, mz_stream_create_cb crypt_create, char *password)
{
char buf[UINT16_MAX];
@ -206,25 +264,30 @@ void test_compress(char *method, mz_stream_create_cb create_compress)
/***************************************************************************/
#ifdef HAVE_AES
void test_aes()
{
test_encrypt("aes", mz_stream_aes_create, "hello");
}
#endif
#ifdef HAVE_PKCRYPT
void test_crypt()
{
test_encrypt("crypt", mz_stream_crypt_create, "hello");
test_encrypt("pkcrypt", mz_stream_pkcrypt_create, "hello");
}
#endif
#ifdef HAVE_ZLIB
void test_zlib()
{
test_compress("zlib", mz_stream_zlib_create);
}
#endif
#ifdef HAVE_BZIP
void test_bzip()
{
test_compress("bzip", mz_stream_bzip_create);
}
#endif
/***************************************************************************/
@ -262,7 +325,9 @@ void test_zip_mem()
file_info.compression_method = MZ_COMPRESS_METHOD_DEFLATE;
file_info.filename = text_name;
file_info.uncompressed_size = text_size;
#ifdef HAVE_AES
file_info.aes_version = MZ_AES_VERSION;
#endif
err = mz_zip_entry_write_open(zip_handle, &file_info, MZ_COMPRESS_LEVEL_DEFAULT, password);
if (err == MZ_OK)