From: Piotr Caban Subject: msvcrt: Added _splitpath_s implementation Message-Id: <4C7A75D7.1090805@codeweavers.com> Date: Sun, 29 Aug 2010 16:59:35 +0200 --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/dir.c | 105 ++++++++++++++++++++++++++++++++---------- dlls/msvcrt/msvcrt.h | 5 ++ dlls/msvcrt/msvcrt.spec | 4 +- 6 files changed, 90 insertions(+), 30 deletions(-) diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 5c68805..b46a24f 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1116,7 +1116,7 @@ @ cdecl _spawnvp(long str ptr) msvcrt._spawnvp @ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe @ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath -@ stub _splitpath_s +@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s @ stub _sprintf_l @ stub _sprintf_p @ stub _sprintf_p_l diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 701e28a..03d8ba1 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -970,7 +970,7 @@ @ cdecl _spawnvp(long str ptr) msvcrt._spawnvp @ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe @ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath -@ stub _splitpath_s +@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s @ stub _sprintf_l @ stub _sprintf_p @ stub _sprintf_p_l diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 965b9c3..cf09d52 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -956,7 +956,7 @@ @ cdecl _spawnvp(long str ptr) msvcrt._spawnvp @ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe @ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath -@ stub _splitpath_s +@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s @ stub _sprintf_l @ stub _sprintf_p @ stub _sprintf_p_l diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index c5b6638..5beb91b 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -745,27 +745,42 @@ int CDECL _wrmdir(const MSVCRT_wchar_t * dir) return -1; } -/********************************************************************* - * _wsplitpath (MSVCRT.@) - * - * Unicode version of _splitpath. +/****************************************************************** + * _splitpath_s (MSVCRT.@) */ -void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT_wchar_t *dir, - MSVCRT_wchar_t *fname, MSVCRT_wchar_t *ext ) +int _splitpath_s(const char* inpath, + char* drive, MSVCRT_size_t sz_drive, + char* dir, MSVCRT_size_t sz_dir, + char* fname, MSVCRT_size_t sz_fname, + char* ext, MSVCRT_size_t sz_ext) { - const MSVCRT_wchar_t *p, *end; + const char *p, *end; + + if (!inpath || (!drive && sz_drive) || + (drive && !sz_drive) || + (!dir && sz_dir) || + (dir && !sz_dir) || + (!fname && sz_fname) || + (fname && !sz_fname) || + (!ext && sz_ext) || + (ext && !sz_ext)) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } if (inpath[0] && inpath[1] == ':') { - if (drv) + if (drive) { - drv[0] = inpath[0]; - drv[1] = inpath[1]; - drv[2] = 0; + if (sz_drive <= 2) goto do_error; + drive[0] = inpath[0]; + drive[1] = inpath[1]; + drive[2] = 0; } inpath += 2; } - else if (drv) drv[0] = 0; + else if (drive) drive[0] = '\0'; /* look for end of directory part */ end = NULL; @@ -775,7 +790,8 @@ void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT { if (dir) { - memcpy( dir, inpath, (end - inpath) * sizeof(MSVCRT_wchar_t) ); + if (sz_dir <= end - inpath) goto do_error; + memcpy( dir, inpath, (end - inpath) ); dir[end - inpath] = 0; } inpath = end; @@ -790,10 +806,33 @@ void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT if (fname) { - memcpy( fname, inpath, (end - inpath) * sizeof(MSVCRT_wchar_t) ); + if (sz_fname <= end - inpath) goto do_error; + memcpy( fname, inpath, (end - inpath) ); fname[end - inpath] = 0; } - if (ext) strcpyW( ext, end ); + if (ext) + { + if (sz_ext <= strlen(end)) goto do_error; + strcpy( 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'; + *MSVCRT__errno() = MSVCRT_ERANGE; + return MSVCRT_ERANGE; +} + +/********************************************************************* + * _splitpath (MSVCRT.@) + */ +void CDECL _splitpath(const char *inpath, char *drv, char *dir, + char *fname, char *ext) +{ + _splitpath_s(inpath, drv, MSVCRT__MAX_DRIVE, dir, MSVCRT__MAX_DIR, + fname, MSVCRT__MAX_FNAME, ext, MSVCRT__MAX_EXT); } /****************************************************************** @@ -809,15 +848,18 @@ int _wsplitpath_s(const MSVCRT_wchar_t* inpath, { 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 || (!drive && sz_drive) || + (drive && !sz_drive) || + (!dir && sz_dir) || + (dir && !sz_dir) || + (!fname && sz_fname) || + (fname && !sz_fname) || + (!ext && sz_ext) || + (ext && !sz_ext)) + { + *MSVCRT__errno() = MSVCRT_EINVAL; + return MSVCRT_EINVAL; + } if (inpath[0] && inpath[1] == ':') { @@ -871,10 +913,23 @@ do_error: if (dir) dir[0] = '\0'; if (fname) fname[0]= '\0'; if (ext) ext[0]= '\0'; + *MSVCRT__errno() = MSVCRT_ERANGE; return MSVCRT_ERANGE; } /********************************************************************* + * _wsplitpath (MSVCRT.@) + * + * Unicode version of _splitpath. + */ +void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT_wchar_t *dir, + MSVCRT_wchar_t *fname, MSVCRT_wchar_t *ext) +{ + _wsplitpath_s(inpath, drv, MSVCRT__MAX_DRIVE, dir, MSVCRT__MAX_DIR, + fname, MSVCRT__MAX_FNAME, ext, MSVCRT__MAX_EXT); +} + +/********************************************************************* * _wfullpath (MSVCRT.@) * * Unicode version of _fullpath. diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 86df133..8e0bd43 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -47,6 +47,11 @@ #define MSVCRT_I64_MIN (-MSVCRT_I64_MAX-1) #define MSVCRT_UI64_MAX (((unsigned __int64)0xffffffff << 32) | 0xffffffff) +#define MSVCRT__MAX_DRIVE 3 +#define MSVCRT__MAX_DIR 256 +#define MSVCRT__MAX_FNAME 256 +#define MSVCRT__MAX_EXT 256 + typedef unsigned short MSVCRT_wchar_t; typedef unsigned short MSVCRT_wint_t; typedef unsigned short MSVCRT_wctype_t; diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index a7371a8..e9ef14a 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -892,8 +892,8 @@ @ cdecl _spawnve(long str ptr ptr) MSVCRT__spawnve @ cdecl _spawnvp(long str ptr) @ cdecl _spawnvpe(long str ptr ptr) MSVCRT__spawnvpe -@ cdecl _splitpath(str ptr ptr ptr ptr) ntdll._splitpath -# stub _splitpath_s +@ cdecl _splitpath(str ptr ptr ptr ptr) +@ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) # stub _sprintf_l # stub _sprintf_p_l # stub _sprintf_s_l