From 3a2dda11e9118f4a3f9438297ac64af1f199f59d Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Sat, 4 Oct 2008 13:37:55 +0200 Subject: [PATCH] msvcrt: Implemented splitpath_s. --- dlls/msvcrt/dir.c | 78 +++++++++++++++++++++++++++++++++++++++++ dlls/msvcrt/msvcrt.h | 5 +++ dlls/msvcrt/msvcrt.spec | 1 + 3 files changed, 84 insertions(+) diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index 5859adf832d..d06242cb147 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -735,6 +735,84 @@ void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT if (ext) strcpyW( ext, end ); } +/****************************************************************** + * _wsplitpath_s (MSVCRT.@) + * + * Secure version of _wsplitpath + */ +int _wsplitpath_s(const MSVCRT_wchar_t* inpath, + MSVCRT_wchar_t* drive, MSVCRT_size_t sz_drive, + MSVCRT_wchar_t* dir, MSVCRT_size_t sz_dir, + MSVCRT_wchar_t* fname, MSVCRT_size_t sz_fname, + MSVCRT_wchar_t* ext, MSVCRT_size_t sz_ext) +{ + const MSVCRT_wchar_t *p, *end; + + if (!inpath) return MSVCRT_EINVAL; + if (!drive && sz_drive) return MSVCRT_EINVAL; + if (drive && !sz_drive) return MSVCRT_EINVAL; + if (!dir && sz_dir) return MSVCRT_EINVAL; + if (dir && !sz_dir) return MSVCRT_EINVAL; + if (!fname && sz_fname) return MSVCRT_EINVAL; + if (fname && !sz_fname) return MSVCRT_EINVAL; + if (!ext && sz_ext) return MSVCRT_EINVAL; + if (ext && !sz_ext) return MSVCRT_EINVAL; + + if (inpath[0] && inpath[1] == ':') + { + if (drive) + { + if (sz_drive <= 2) goto do_error; + drive[0] = inpath[0]; + drive[1] = inpath[1]; + drive[2] = 0; + } + inpath += 2; + } + else if (drive) drive[0] = '\0'; + + /* look for end of directory part */ + end = NULL; + for (p = inpath; *p; p++) if (*p == '/' || *p == '\\') end = p + 1; + + if (end) /* got a directory */ + { + if (dir) + { + if (sz_dir <= end - inpath) goto do_error; + memcpy( dir, inpath, (end - inpath) * sizeof(MSVCRT_wchar_t) ); + dir[end - inpath] = 0; + } + inpath = end; + } + else if (dir) dir[0] = 0; + + /* look for extension: what's after the last dot */ + end = NULL; + for (p = inpath; *p; p++) if (*p == '.') end = p; + + if (!end) end = p; /* there's no extension */ + + if (fname) + { + if (sz_fname <= end - inpath) goto do_error; + memcpy( fname, inpath, (end - inpath) * sizeof(MSVCRT_wchar_t) ); + fname[end - inpath] = 0; + } + if (ext) + { + if (sz_ext <= strlenW(end)) goto do_error; + strcpyW( ext, end ); + } + return 0; +do_error: + if (drive) drive[0] = '\0'; + if (dir) dir[0] = '\0'; + if (fname) fname[0]= '\0'; + if (ext) ext[0]= '\0'; + return MSVCRT_ERANGE; +} + /********************************************************************* * _wfullpath (MSVCRT.@) * diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index b9aea53783e..73862dc4df0 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -403,6 +403,11 @@ struct MSVCRT__stat64 { #define MSVCRT__IOLBF 0x0040 #define MSVCRT_FILENAME_MAX 260 +#define MSVCRT_DRIVE_MAX 3 +#define MSVCRT_FNAME_MAX 256 +#define MSVCRT_DIR_MAX 256 +#define MSVCRT_EXT_MAX 256 +#define MSVCRT_PATH_MAX 260 #define MSVCRT_stdin (MSVCRT__iob+MSVCRT_STDIN_FILENO) #define MSVCRT_stdout (MSVCRT__iob+MSVCRT_STDOUT_FILENO) #define MSVCRT_stderr (MSVCRT__iob+MSVCRT_STDERR_FILENO) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index c54d33e7286..0da6a251022 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -571,6 +571,7 @@ @ cdecl _wspawnvp(long wstr ptr) @ cdecl _wspawnvpe(long wstr ptr ptr) @ cdecl _wsplitpath(wstr wstr wstr wstr wstr) +@ cdecl _wsplitpath_s(wstr ptr long ptr long ptr long ptr long) _wsplitpath_s @ cdecl _wstat(wstr ptr) MSVCRT__wstat @ cdecl _wstati64(wstr ptr) MSVCRT__wstati64 @ cdecl _wstat64(wstr ptr) MSVCRT__wstat64