From b15a498f1946a873f3498d9599433e7764d44423 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Thu, 1 Feb 2018 18:51:44 +0100 Subject: [PATCH] lib-sieve: util: realpath: Improved conditional expressions in path_normalize() to match the earlier adjusted assertions. Added some more assertions in the process to make sure subtractions are always valid. --- src/lib-sieve/util/realpath.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/lib-sieve/util/realpath.c b/src/lib-sieve/util/realpath.c index b13a2d971..a9e380403 100644 --- a/src/lib-sieve/util/realpath.c +++ b/src/lib-sieve/util/realpath.c @@ -75,14 +75,16 @@ static int path_normalize(const char *path, bool resolve_links, /* a reference to this segment; nothing to do */ } else if (seglen == 2 && p[0] == '.' && p[1] == '.') { /* a reference to parent segment; back up to previous slash */ - if (npath_pos > npath + 1) { + i_assert(npath_pos >= npath); + if ((npath_pos - npath) > 1) { if (*(npath_pos-1) == '/') npath_pos--; for (; *(npath_pos-1) != '/'; npath_pos--); } } else { /* allocate space if necessary */ - if ((npath_pos + seglen + 1) >= (npath + asize)) { + i_assert(npath_pos >= npath); + if ((size_t)((npath_pos - npath) + seglen + 1) >= asize) { ptrdiff_t npath_offset = npath_pos - npath; asize = nearest_power(npath_offset + seglen + 2); npath = t_buffer_reget(npath, asize); @@ -90,8 +92,8 @@ static int path_normalize(const char *path, bool resolve_links, } /* make sure npath now ends in slash */ + i_assert(npath_pos > npath); if (*(npath_pos-1) != '/') { - i_assert(npath_pos >= npath); i_assert((size_t)((npath_pos - npath) + 1) < asize); *(npath_pos++) = '/'; } @@ -129,7 +131,8 @@ static int path_normalize(const char *path, bool resolve_links, [npath][0][preserved tail][link buffer][room for tail][0] */ espace = ltlen + tlen + 2; - if ((npath_pos + espace + lsize) >= (npath + asize)) { + i_assert(npath_pos >= npath); + if ((size_t)((npath_pos - npath) + espace + lsize) >= asize) { ptrdiff_t npath_offset = npath_pos - npath; asize = nearest_power((npath_offset + espace + lsize) + 1); lsize = asize - (npath_offset + espace); @@ -171,8 +174,9 @@ static int path_normalize(const char *path, bool resolve_links, we need to allocate more space as well if lsize == ret, because the returned link may have gotten truncated */ espace = ltlen + tlen + 2; - if ((npath_pos + espace + lsize) >= (npath + asize) || - lsize == (size_t)ret) { + i_assert(npath_pos >= npath); + if ((size_t)((npath_pos - npath) + espace + lsize) >= asize || + lsize == (size_t)ret) { ptrdiff_t npath_offset = npath_pos - npath; asize = nearest_power((npath_offset + espace + lsize) + 1); lsize = asize - (npath_offset + espace); @@ -202,7 +206,8 @@ static int path_normalize(const char *path, bool resolve_links, npath_pos = npath + 1; } else { /* relative symlink; back up to previous segment */ - if (npath_pos > npath + 1) { + i_assert(npath_pos >= npath); + if ((npath_pos - npath) > 1) { if (*(npath_pos-1) == '/') npath_pos--; for (; *(npath_pos-1) != '/'; npath_pos--); @@ -223,7 +228,7 @@ static int path_normalize(const char *path, bool resolve_links, i_assert((size_t)(npath_pos - npath) < asize); /* remove any trailing slash */ - if (npath_pos > npath + 1 && *(npath_pos-1) == '/') + if ((npath_pos - npath) > 1 && *(npath_pos-1) == '/') npath_pos--; *npath_pos = '\0';