use BLI_strncpy and BLI_snprintf when the size of the string is known.
[blender.git] / source / blender / blenlib / intern / path_util.c
index 7aa8452..6d63105 100644 (file)
@@ -44,6 +44,7 @@
 #include "BLI_fileops.h"
 #include "BLI_path_util.h"
 #include "BLI_string.h"
+#include "BLI_string_utf8.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_utildefines.h"
@@ -220,16 +221,25 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
        }
 
        if(unique_check(arg, name)) {
+               char    numstr[16];
                char    tempname[UNIQUE_NAME_MAX];
                char    left[UNIQUE_NAME_MAX];
                int             number;
                int             len= BLI_split_name_num(left, &number, name, delim);
                do {
-                       int newlen= BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, ++number);
-                       if(newlen >= name_len) {
-                               len -= ((newlen + 1) - name_len);
-                               if(len < 0) len= number= 0;
-                               left[len]= '\0';
+                       int numlen= BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number);
+
+                       /* highly unlikely the string only has enough room for the number
+                        * but support anyway */
+                       if ((len == 0) || (numlen >= name_len)) {
+                               /* number is know not to be utf-8 */
+                               BLI_strncpy(tempname, numstr, name_len);
+                       }
+                       else {
+                               char *tempname_buf;
+                               tempname[0]= '\0';
+                               tempname_buf =BLI_strncat_utf8(tempname, left, name_len - numlen);
+                               memcpy(tempname_buf, numstr, numlen + 1);
                        }
                } while(unique_check(arg, tempname));
 
@@ -307,7 +317,7 @@ void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char deli
 
 void BLI_cleanup_path(const char *relabase, char *dir)
 {
-       short a;
+       ptrdiff_t a;
        char *start, *eind;
        if (relabase) {
                BLI_path_abs(dir, relabase);
@@ -416,8 +426,8 @@ void BLI_cleanup_file(const char *relabase, char *dir)
 void BLI_path_rel(char *file, const char *relfile)
 {
        char * lslash;
-       char temp[FILE_MAXDIR+FILE_MAXFILE];
-       char res[FILE_MAXDIR+FILE_MAXFILE];
+       char temp[FILE_MAX];
+       char res[FILE_MAX];
        
        /* if file is already relative, bail out */
        if(file[0]=='/' && file[1]=='/') return;
@@ -435,9 +445,9 @@ void BLI_path_rel(char *file, const char *relfile)
                if (relfile[0] != '\\' && relfile[0] != '/') {
                        ptemp++;
                }
-               BLI_strncpy(ptemp, relfile, FILE_MAXDIR + FILE_MAXFILE-3);
+               BLI_strncpy(ptemp, relfile, FILE_MAX-3);
        } else {
-               BLI_strncpy(temp, relfile, FILE_MAXDIR + FILE_MAXFILE);
+               BLI_strncpy(temp, relfile, FILE_MAX);
        }
 
        if (BLI_strnlen(file, 3) > 2) {
@@ -529,7 +539,7 @@ int BLI_has_parent(char *path)
 int BLI_parent_dir(char *path)
 {
        static char parent_dir[]= {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
-       char tmp[FILE_MAXDIR+FILE_MAXFILE+4];
+       char tmp[FILE_MAX+4];
        BLI_strncpy(tmp, path, sizeof(tmp)-4);
        BLI_add_slash(tmp);
        strcat(tmp, parent_dir);
@@ -617,8 +627,10 @@ int BLI_path_frame_range(char *path, int sta, int end, int digits)
 
        if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
                char tmp[FILE_MAX];
-               sprintf(tmp, "%.*s%.*d-%.*d%s", ch_sta, path, ch_end-ch_sta, sta, ch_end-ch_sta, end, path+ch_end);
-               strcpy(path, tmp);
+               BLI_snprintf(tmp, sizeof(tmp),
+                            "%.*s%.*d-%.*d%s",
+                            ch_sta, path, ch_end-ch_sta, sta, ch_end-ch_sta, end, path+ch_end);
+               BLI_strncpy(path, tmp, FILE_MAX);
                return 1;
        }
        return 0;
@@ -734,7 +746,7 @@ int BLI_path_cwd(char *path)
 #endif
        
        if (wasrelative==1) {
-               char cwd[FILE_MAXDIR + FILE_MAXFILE]= "";
+               char cwd[FILE_MAX]= "";
                BLI_current_working_dir(cwd, sizeof(cwd)); /* incase the full path to the blend isnt used */
                
                if (cwd[0] == '\0') {
@@ -747,8 +759,8 @@ int BLI_path_cwd(char *path)
                        * blend file which isnt a feature we want to use in this case since were dealing
                        * with a path from the command line, rather than from inside Blender */
                        
-                       char origpath[FILE_MAXDIR + FILE_MAXFILE];
-                       BLI_strncpy(origpath, path, FILE_MAXDIR + FILE_MAXFILE);
+                       char origpath[FILE_MAX];
+                       BLI_strncpy(origpath, path, FILE_MAX);
                        
                        BLI_make_file_string(NULL, path, cwd, origpath); 
                }
@@ -1246,7 +1258,7 @@ void BLI_make_exist(char *dir)
 
 void BLI_make_existing_file(const char *name)
 {
-       char di[FILE_MAXDIR+FILE_MAXFILE], fi[FILE_MAXFILE];
+       char di[FILE_MAX], fi[FILE_MAXFILE];
 
        BLI_strncpy(di, name, sizeof(di));
        BLI_splitdirstring(di, fi);
@@ -1406,7 +1418,7 @@ int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
 {
        size_t path_len= strlen(path);
        size_t ext_len= strlen(ext);
-       size_t a;
+       ssize_t a;
 
        for(a= path_len - 1; a >= 0; a--) {
                if (ELEM3(path[a], '.', '/', '\\')) {
@@ -1414,6 +1426,10 @@ int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
                }
        }
 
+       if ((a < 0) || (path[a] != '.')) {
+               a= path_len;
+       }
+
        if(a + ext_len >= maxlen)
                return 0;
 
@@ -1426,7 +1442,7 @@ int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
 {
        size_t path_len= strlen(path);
        size_t ext_len= strlen(ext);
-       size_t a;
+       ssize_t a;
 
        /* first check the extension is alread there */
        if (    (ext_len <= path_len) &&
@@ -1691,8 +1707,8 @@ static int add_win32_extension(char *name)
        type = BLI_exists(name);
        if ((type == 0) || S_ISDIR(type)) {
 #ifdef _WIN32
-               char filename[FILE_MAXDIR+FILE_MAXFILE];
-               char ext[FILE_MAXDIR+FILE_MAXFILE];
+               char filename[FILE_MAX];
+               char ext[FILE_MAX];
                const char *extensions = getenv("PATHEXT");
                if (extensions) {
                        char *temp;
@@ -1738,7 +1754,7 @@ static int add_win32_extension(char *name)
 */
 static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name)
 {
-       char filename[FILE_MAXDIR+FILE_MAXFILE];
+       char filename[FILE_MAX];
        const char *path = NULL, *temp;
 
 #ifdef _WIN32
@@ -1841,7 +1857,7 @@ const char *BLI_program_dir(void)
 * @param fullname The full path to the temp directory
 * @param userdir Directory specified in user preferences 
 */
-void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir)
+static void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir)
 {
        fullname[0] = '\0';