From: "Mark E." To: djgpp-workers AT delorie DOT com Date: Sat, 21 Sep 2002 15:35:50 -0400 MIME-Version: 1.0 Subject: Re: working toward a realpath implementation Message-ID: <3D8C91D6.6086.68FEE1@localhost> In-reply-to: <3277-Sat21Sep2002163736+0300-eliz@is.elta.co.il> References: <3D8C381A DOT 23922 DOT 6045C AT localhost> (snowball3 AT softhome DOT net) X-mailer: Pegasus Mail for Windows (v4.02a) Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Content-description: Mail message body Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk This version of the update adds a buffer size parameter to __canonicalize_path to permit a safer wrapper function to added in the future should it be added to a future posix standard. Index: fixpath.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fixpath.c,v retrieving revision 1.7 diff -c -p -r1.7 fixpath.c *** fixpath.c 17 Oct 2001 05:08:39 -0000 1.7 --- fixpath.c 21 Sep 2002 19:34:56 -0000 *************** is_term(int c) *** 117,123 **** return c == '/' || c == '\\' || c == '\0'; } ! /* Takes as input an arbitrary path. Fixes up the path by: 1. Removing consecutive slashes 2. Removing trailing slashes 3. Making the path absolute if it wasn't already --- 117,124 ---- return c == '/' || c == '\\' || c == '\0'; } ! /* Wrapper for the functions realpath and _fixpath. ! Takes as input an arbitrary path. Fixes up the path by: 1. Removing consecutive slashes 2. Removing trailing slashes 3. Making the path absolute if it wasn't already *************** is_term(int c) *** 125,133 **** 5. Removing ".." entries in the path (and the directory above them) 6. Adding a drive specification if one wasn't there 7. Converting all slashes to '/' ! */ ! void ! _fixpath(const char *in, char *out) { int drive_number; char in1[FILENAME_MAX]; --- 126,135 ---- 5. Removing ".." entries in the path (and the directory above them) 6. Adding a drive specification if one wasn't there 7. Converting all slashes to '/' ! */ ! ! char * ! __canonicalize_path(const char *in, char *out, size_t path_max) { int drive_number; char in1[FILENAME_MAX]; *************** _fixpath(const char *in, char *out) *** 136,144 **** --- 138,152 ---- int preserve_case = _preserve_fncase(); char *name_start; int mbsize; + char *op_limit; use_lfn = _use_lfn(in); + if (path_max > FILENAME_MAX) + path_max = FILENAME_MAX; + + op_limit = op + path_max; + /* Perform the same magic conversions that _put_path does. */ _put_path(in); dosmemget(__tb, sizeof(in1), in1); *************** _fixpath(const char *in, char *out) *** 160,166 **** if (*ip <= 'Z') *op++ = drive_number + 'a'; else ! *op++ = *ip; ++ip; } *op++ = *ip++; --- 168,174 ---- if (*ip <= 'Z') *op++ = drive_number + 'a'; else ! * op++ = *ip; ++ip; } *op++ = *ip++; *************** _fixpath(const char *in, char *out) *** 213,218 **** --- 221,233 ---- continue; } + /* Buffer overflow check. */ + if (op >= op_limit) + { + errno = ENAMETOOLONG; + return NULL; + } + /* Copy path component from in to out */ *op++ = '/'; #if 0 *************** _fixpath(const char *in, char *out) *** 229,234 **** --- 244,256 ---- } else *op++ = *ip++; + + /* Check for buffer overflow. */ + if (op >= op_limit) + { + errno = ENAMETOOLONG; + return NULL; + } } #endif } *************** _fixpath(const char *in, char *out) *** 236,248 **** /* If root directory, insert trailing slash */ if (op == out + 2) *op++ = '/'; /* Null terminate the output */ *op = '\0'; /* switch FOO\BAR to foo/bar, downcase where appropriate */ for (op = out + 3, name_start = op - 1; *name_start; op++) { ! char long_name[FILENAME_MAX]; #if 1 /* skip multibyte character */ --- 258,277 ---- /* If root directory, insert trailing slash */ if (op == out + 2) *op++ = '/'; + /* Check for buffer overflow. */ + if (op >= op_limit) + { + errno = ENAMETOOLONG; + return NULL; + } + /* Null terminate the output */ *op = '\0'; /* switch FOO\BAR to foo/bar, downcase where appropriate */ for (op = out + 3, name_start = op - 1; *name_start; op++) { ! char long_name[path_max]; #if 1 /* skip multibyte character */ *************** _fixpath(const char *in, char *out) *** 286,291 **** --- 315,328 ---- else if (*op == '\0') break; } + + return out; + } + + void + _fixpath(const char *in, char *out) + { + __canonicalize_path(in, out, FILENAME_MAX); } #ifdef TEST