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';