[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-403-g0ae61e2

Jeremy Allison jra at samba.org
Fri Nov 30 21:09:39 GMT 2007


The branch, v3-2-test has been updated
       via  0ae61e26547e594e94037d4474a008221e5df8cf (commit)
      from  d5658914c2d6ec878d9a11f8a1fa57f1697362e3 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 0ae61e26547e594e94037d4474a008221e5df8cf
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Nov 30 13:09:04 2007 -0800

    Add talloc versions of all the next_token() functions.
    Now I can really start removing fixed length strings...
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source/lib/util_str.c        |  105 ++++-
 source/libsmb/libsmbclient.c | 1333 +++++++++++++++++++++++-------------------
 2 files changed, 830 insertions(+), 608 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index f5a50b3..886ae2a 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -85,6 +85,73 @@ static bool next_token_internal(const char **ptr,
 	return(true);
 }
 
+static bool next_token_internal_talloc(TALLOC_CTX *ctx,
+				const char **ptr,
+                                char **pp_buff,
+                                const char *sep,
+                                bool ltrim)
+{
+	char *s;
+	char *pbuf;
+	bool quoted;
+	size_t len=1;
+
+	*pp_buff = NULL;
+	if (!ptr) {
+		return(false);
+	}
+
+	s = (char *)*ptr;
+
+	/* default to simple separators */
+	if (!sep) {
+		sep = " \t\n\r";
+	}
+
+	/* find the first non sep char, if left-trimming is requested */
+	if (ltrim) {
+		while (*s && strchr_m(sep,*s))
+			s++;
+	}
+
+	/* nothing left? */
+	if (!*s) {
+		return(false);
+	}
+
+	/* Work out the length needed. */
+	for (quoted = false; *s &&
+			(quoted || !strchr_m(sep,*s)); s++) {
+		if (*s == '\"') {
+			quoted = !quoted;
+		} else {
+			len++;
+		}
+	}
+
+	/* We started with len = 1 so we have space for the nul. */
+	*pp_buff = TALLOC_ARRAY(ctx, char, len);
+	if (!*pp_buff) {
+		return false;
+	}
+
+	/* copy over the token */
+	pbuf = *pp_buff;
+	for (quoted = false; *s &&
+			(quoted || !strchr_m(sep,*s)); s++) {
+		if ( *s == '\"' ) {
+			quoted = !quoted;
+		} else {
+			*pbuf++ = *s;
+		}
+	}
+
+	*ptr = (*s) ? s+1 : s;
+	*pbuf = 0;
+
+	return true;
+}
+
 /*
  * Get the next token from a string, return false if none found.  Handles
  * double-quotes.  This version trims leading separator characters before
@@ -92,7 +159,15 @@ static bool next_token_internal(const char **ptr,
  */
 bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
 {
-    return next_token_internal(ptr, buff, sep, bufsize, true);
+	return next_token_internal(ptr, buff, sep, bufsize, true);
+}
+
+bool next_token_talloc(TALLOC_CTX *ctx,
+			const char **ptr,
+			char **pp_buff,
+			const char *sep)
+{
+	return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
 }
 
 /*
@@ -105,7 +180,15 @@ bool next_token_no_ltrim(const char **ptr,
                          const char *sep,
                          size_t bufsize)
 {
-    return next_token_internal(ptr, buff, sep, bufsize, false);
+	return next_token_internal(ptr, buff, sep, bufsize, false);
+}
+
+bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
+			const char **ptr,
+			char **pp_buff,
+			const char *sep)
+{
+	return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
 }
 
 /**
@@ -119,14 +202,30 @@ static const char *last_ptr=NULL;
 bool next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
 {
 	bool ret;
-	if (!ptr)
+	if (!ptr) {
 		ptr = &last_ptr;
+	}
 
 	ret = next_token(ptr, buff, sep, bufsize);
 	last_ptr = *ptr;
 	return ret;
 }
 
+bool next_token_nr_talloc(TALLOC_CTX *ctx,
+				const char **ptr,
+				char **pp_buff,
+				const char *sep)
+{
+	bool ret;
+	if (!ptr) {
+		ptr = &last_ptr;
+	}
+
+	ret = next_token_talloc(ctx, ptr, pp_buff, sep);
+	last_ptr = *ptr;
+	return ret;
+}
+
 void set_first_token(char *ptr)
 {
 	last_ptr = ptr;
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index b20b1ca..c81002b 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -132,6 +132,7 @@ hex2int( unsigned int _char )
 
 /*
  * smbc_urldecode()
+ * and smbc_urldecode_talloc() (internal fn.)
  *
  * Convert strings of %xx to their single character equivalent.  Each 'x' must
  * be a valid hexadecimal digit, or that % sequence is left undecoded.
@@ -141,53 +142,87 @@ hex2int( unsigned int _char )
  * Returns the number of % sequences which could not be converted due to lack
  * of two following hexadecimal digits.
  */
-int
-smbc_urldecode(char *dest, char * src, size_t max_dest_len)
+static int
+smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src)
 {
-        int old_length = strlen(src);
-        int i = 0;
-        int err_count = 0;
-        pstring temp;
-        char * p;
+	int old_length = strlen(src);
+	int i = 0;
+	int err_count = 0;
+	size_t newlen = 1;
+	char *p, *dest;
+
+	*pp_dest = NULL;
+	if (old_length == 0) {
+		return 0;
+	}
 
-        if ( old_length == 0 ) {
-                return 0;
-        }
+	for (i = 0; i < old_length; ) {
+		unsigned char character = src[i++];
+
+		if (character == '%') {
+			int a = i+1 < old_length ? hex2int(src[i]) : -1;
+			int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
 
-        p = temp;
-        while ( i < old_length ) {
-                unsigned char character = src[ i++ ];
+			/* Replace valid sequence */
+			if (a != -1 && b != -1) {
+				/* Replace valid %xx sequence with %dd */
+				character = (a * 16) + b;
+				if (character == '\0') {
+					break; /* Stop at %00 */
+				}
+				i += 2;
+			} else {
+				err_count++;
+			}
+		}
+		newlen++;
+	}
+
+	dest = TALLOC_ARRAY(ctx, char, newlen);
+	if (!dest) {
+		return err_count;
+	}
+
+	err_count = 0;
+	for (p = dest, i = 0; i < old_length; ) {
+                unsigned char character = src[i++];
 
                 if (character == '%') {
-                        int a = i+1 < old_length ? hex2int( src[i] ) : -1;
-                        int b = i+1 < old_length ? hex2int( src[i+1] ) : -1;
+                        int a = i+1 < old_length ? hex2int(src[i]) : -1;
+                        int b = i+1 < old_length ? hex2int(src[i+1]) : -1;
 
                         /* Replace valid sequence */
                         if (a != -1 && b != -1) {
-
                                 /* Replace valid %xx sequence with %dd */
                                 character = (a * 16) + b;
-
                                 if (character == '\0') {
                                         break; /* Stop at %00 */
                                 }
-
                                 i += 2;
                         } else {
-
                                 err_count++;
                         }
                 }
-
                 *p++ = character;
         }
 
         *p = '\0';
+	*pp_dest = dest;
+        return err_count;
+}
 
-        strncpy(dest, temp, max_dest_len - 1);
-        dest[max_dest_len - 1] = '\0';
+int
+smbc_urldecode(char *dest, char *src, size_t max_dest_len)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	char *pdest;
+	int ret = smbc_urldecode_talloc(frame, &pdest, src);
 
-        return err_count;
+	if (pdest) {
+		strlcpy(dest, pdest, max_dest_len);
+	}
+	TALLOC_FREE(frame);
+	return ret;
 }
 
 /*
@@ -199,7 +234,7 @@ smbc_urldecode(char *dest, char * src, size_t max_dest_len)
  * Returns the remaining buffer length.
  */
 int
-smbc_urlencode(char * dest, char * src, int max_dest_len)
+smbc_urlencode(char *dest, char *src, int max_dest_len)
 {
         char hex[] = "0123456789ABCDEF";
 
@@ -226,7 +261,7 @@ smbc_urlencode(char * dest, char * src, int max_dest_len)
 
         *dest++ = '\0';
         max_dest_len--;
-        
+
         return max_dest_len;
 }
 
@@ -270,37 +305,46 @@ smbc_urlencode(char * dest, char * src, int max_dest_len)
 static const char *smbc_prefix = "smb:";
 
 static int
-smbc_parse_path(SMBCCTX *context,
+smbc_parse_path(TALLOC_CTX *ctx,
+		SMBCCTX *context,
                 const char *fname,
-                char *workgroup, int workgroup_len,
-                char *server, int server_len,
-                char *share, int share_len,
-                char *path, int path_len,
-		char *user, int user_len,
-                char *password, int password_len,
-                char *options, int options_len)
+                char **pp_workgroup,
+                char **pp_server,
+                char **pp_share,
+                char **pp_path,
+		char **pp_user,
+                char **pp_password,
+                char **pp_options)
 {
-	static pstring s;
-	pstring userinfo;
+	char *s;
 	const char *p;
 	char *q, *r;
 	int len;
 
-	server[0] = share[0] = path[0] = user[0] = password[0] = (char)0;
+	/* Ensure these returns are at least valid pointers. */
+	*pp_server = talloc_strdup(ctx, "");
+	*pp_share = talloc_strdup(ctx, "");
+	*pp_path = talloc_strdup(ctx, "");
+	*pp_user = talloc_strdup(ctx, "");
+	*pp_password = talloc_strdup(ctx, "");
+
+	if (!*pp_server || !*pp_share || !*pp_path ||
+			!*pp_user || !*pp_password) {
+		return -1;
+	}
 
         /*
          * Assume we wont find an authentication domain to parse, so default
          * to the workgroup in the provided context.
          */
-        if (workgroup != NULL) {
-                strncpy(workgroup, context->workgroup, workgroup_len - 1);
-                workgroup[workgroup_len - 1] = '\0';
-        }
+	if (pp_workgroup != NULL) {
+		*pp_workgroup = talloc_strdup(ctx, context->workgroup);
+	}
 
-        if (options != NULL && options_len > 0) {
-                options[0] = (char)0;
-        }
-	pstrcpy(s, fname);
+	if (pp_options) {
+		*pp_options = talloc_strdup(ctx, "");
+	}
+	s = talloc_strdup(ctx, fname);
 
 	/* see if it has the right prefix */
 	len = strlen(smbc_prefix);
@@ -313,10 +357,8 @@ smbc_parse_path(SMBCCTX *context,
 	/* Watch the test below, we are testing to see if we should exit */
 
 	if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) {
-
                 DEBUG(1, ("Invalid path (does not begin with smb://"));
 		return -1;
-
 	}
 
 	p += 2;  /* Skip the double slash */
@@ -325,17 +367,19 @@ smbc_parse_path(SMBCCTX *context,
         if ((q = strrchr(p, '?')) != NULL ) {
                 /* There are options.  Null terminate here and point to them */
                 *q++ = '\0';
-                
+
                 DEBUG(4, ("Found options '%s'", q));
 
-                /* Copy the options */
-                if (options != NULL && options_len > 0) {
-                        safe_strcpy(options, q, options_len - 1);
-                }
-        }
+		/* Copy the options */
+		if (*pp_options != NULL) {
+			TALLOC_FREE(*pp_options);
+			*pp_options = talloc_strdup(ctx, q);
+		}
+	}
 
-	if (*p == (char)0)
-	    goto decoding;
+	if (*p == '\0') {
+		goto decoding;
+	}
 
 	if (*p == '/') {
 		int wl = strlen(context->workgroup);
@@ -344,13 +388,16 @@ smbc_parse_path(SMBCCTX *context,
 			wl = 16;
 		}
 
-		strncpy(server, context->workgroup, wl);
-                server[wl] = '\0';
+		*pp_server = talloc_strdup(ctx, context->workgroup);
+		if (!*pp_server) {
+			return -1;
+		}
+               	*pp_server[wl] = '\0';
 		return 0;
 	}
 
 	/*
-	 * ok, its for us. Now parse out the server, share etc. 
+	 * ok, its for us. Now parse out the server, share etc.
 	 *
 	 * However, we want to parse out [[domain;]user[:password]@] if it
 	 * exists ...
@@ -360,81 +407,78 @@ smbc_parse_path(SMBCCTX *context,
 	q = strchr_m(p, '@');
 	r = strchr_m(p, '/');
 	if (q && (!r || q < r)) {
-		pstring username, passwd, domain;
-		const char *u = userinfo;
-
-		next_token_no_ltrim(&p, userinfo, "@", sizeof(fstring));
+		char *userinfo = NULL;
+		const char *u;
 
-		username[0] = passwd[0] = domain[0] = 0;
+		next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@");
+		if (!userinfo) {
+			return -1;
+		}
+		u = userinfo;
 
 		if (strchr_m(u, ';')) {
-      
-			next_token_no_ltrim(&u, domain, ";", sizeof(fstring));
-
+			char *workgroup;
+			next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
+			if (!workgroup) {
+				return -1;
+			}
+			if (pp_workgroup) {
+				*pp_workgroup = workgroup;
+			}
 		}
 
 		if (strchr_m(u, ':')) {
-
-			next_token_no_ltrim(&u, username, ":", sizeof(fstring));
-
-			pstrcpy(passwd, u);
-
-		}
-		else {
-
-			pstrcpy(username, u);
-
+			next_token_no_ltrim_talloc(ctx, &u, pp_user, ":");
+			if (!*pp_user) {
+				return -1;
+			}
+			*pp_password = talloc_strdup(ctx, u);
+			if (!*pp_password) {
+				return -1;
+			}
+		} else {
+			*pp_user = talloc_strdup(ctx, u);
+			if (!*pp_user) {
+				return -1;
+			}
 		}
-
-                if (domain[0] && workgroup) {
-                        strncpy(workgroup, domain, workgroup_len - 1);
-                        workgroup[workgroup_len - 1] = '\0';
-                }
-
-		if (username[0]) {
-			strncpy(user, username, user_len - 1);
-                        user[user_len - 1] = '\0';
-                }
-
-		if (passwd[0]) {
-			strncpy(password, passwd, password_len - 1);
-                        password[password_len - 1] = '\0';
-                }
-
 	}
 
-	if (!next_token(&p, server, "/", sizeof(fstring))) {
-
+	if (!next_token_talloc(ctx, &p, pp_server, "/")) {
 		return -1;
-
 	}
 
-	if (*p == (char)0) goto decoding;  /* That's it ... */
-  
-	if (!next_token(&p, share, "/", sizeof(fstring))) {
+	if (*p == (char)0) {
+		goto decoding;  /* That's it ... */
+	}
 
+	if (!next_token_talloc(ctx, &p, pp_share, "/")) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list