util: fixed generate_unique_strs() to be portable
authorAndrew Tridgell <tridge@samba.org>
Mon, 19 Oct 2009 11:47:45 +0000 (22:47 +1100)
committerAndrew Tridgell <tridge@samba.org>
Mon, 19 Oct 2009 11:47:45 +0000 (22:47 +1100)
'place' was going negative, and giving undefined results. The result
was duplicate names which gave errors in SMB2-DIR on PPC and other
systems.

lib/util/genrand.c

index 8c7d88a112b5f36c152d98cde220ca8d68d9df64..6002c0647eac4d4bba462cd7e53d1f2913a5abbe 100644 (file)
@@ -361,24 +361,6 @@ again:
        return retstr;
 }
 
-/**
- * Define our own pow() function to avoid linking in libm
- */
-static double s_pow(double x, double y)
-{
-       int i;
-       double ret = x;
-
-       if (y == 0)
-               return 1;
-
-       for (i = 1; i < y; i++)
-               ret *= x;
-
-       return ret;
-}
-
-
 /**
  * Generate an array of unique text strings all of the same length.
  * The returned string will be allocated.
@@ -390,30 +372,30 @@ _PUBLIC_ char** generate_unique_strs(TALLOC_CTX *mem_ctx, size_t len,
                                     uint32_t num)
 {
        const char *c_list = "abcdefghijklmnopqrstuvwxyz0123456789+_-#.,";
-       const int c_size = 42;
-       int i, j, rem;
+       const unsigned c_size = 42;
+       int i, j;
+       unsigned rem;
        long long place;
        char ** strs = NULL;
 
        if (num == 0 || len == 0)
                return NULL;
 
-       /* We'll never return more than UINT32_MAX strings. Since 42^6 is more
-        * than UINT32_MAX, we only have to check if we've been asked to return
-        * more than the total number of permutations for lengths less than 6.*/
-       if ((len < 6) && (num > s_pow(c_size, len)))
-               return NULL;
-
        strs = talloc_array(mem_ctx, char *, num);
+       if (strs == NULL) return NULL;
 
        for (i = 0; i < num; i++) {
-               char *retstr = (char *)talloc_zero_size(mem_ctx, len + 1);
+               char *retstr = (char *)talloc_size(strs, len + 1);
+               if (retstr == NULL) {
+                       talloc_free(strs);
+                       return NULL;
+               }
                rem = i;
-               for (j = len - 1; j >= 0; j--) {
-                       place = s_pow(c_size, j);
-                       retstr[j] = c_list[rem / place];
-                       rem = rem % place;
+               for (j = 0; j < len; j++) {
+                       retstr[j] = c_list[rem % c_size];
+                       rem = rem / c_size;
                }
+               retstr[j] = 0;
                strs[i] = retstr;
        }