]> granicus.if.org Git - curl/commitdiff
ldap: Fixed support for Unicode attributes in Win32 search call
authorSteve Holme <steve_holme@hotmail.com>
Sat, 3 Jan 2015 20:49:11 +0000 (20:49 +0000)
committerSteve Holme <steve_holme@hotmail.com>
Sun, 4 Jan 2015 14:27:51 +0000 (14:27 +0000)
lib/ldap.c

index 2b4b168ede602d9139d17541c43d4a2e2ec87d58..a10094c779377553dd0fd3447a5d9d3cf3706178 100644 (file)
@@ -84,10 +84,11 @@ typedef struct {
 #if defined(CURL_LDAP_WIN) && \
     (defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI))
   TCHAR  *lud_dn;
+  TCHAR **lud_attrs;
 #else
   char   *lud_dn;
-#endif
   char  **lud_attrs;
+#endif
   int     lud_scope;
   char   *lud_filter;
   char  **lud_exts;
@@ -645,24 +646,34 @@ static int str2scope (const char *p)
 
 /*
  * Split 'str' into strings separated by commas.
- * Note: res[] points into 'str'.
+ * Note: out[] points into 'str'.
  */
-static char **split_str (char *str)
+static bool split_str(char *str, char ***out, size_t *count)
 {
-  char **res, *lasts, *s;
-  int  i;
-
-  for(i = 2, s = strchr(str,','); s; i++)
-    s = strchr(++s,',');
+  char **res;
+  char *lasts;
+  char *s;
+  size_t  i;
+  size_t items = 1;
+
+  s = strchr(str, ',');
+  while(s) {
+    items++;
+    s = strchr(++s, ',');
+  }
 
-  res = calloc(i, sizeof(char*));
+  res = calloc(items, sizeof(char *));
   if(!res)
-    return NULL;
+    return FALSE;
 
-  for(i = 0, s = strtok_r(str, ",", &lasts); s;
+  for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items;
       s = strtok_r(NULL, ",", &lasts), i++)
     res[i] = s;
-  return res;
+
+  *out = res;
+  *count = items;
+
+  return TRUE;
 }
 
 /*
@@ -670,22 +681,12 @@ static char **split_str (char *str)
  */
 static bool unescape_elements (void *data, LDAPURLDesc *ludp)
 {
-  int i;
-
   if(ludp->lud_filter) {
     ludp->lud_filter = curl_easy_unescape(data, ludp->lud_filter, 0, NULL);
     if(!ludp->lud_filter)
        return FALSE;
   }
 
-  for(i = 0; ludp->lud_attrs && ludp->lud_attrs[i]; i++) {
-    ludp->lud_attrs[i] = curl_easy_unescape(data, ludp->lud_attrs[i],
-                                            0, NULL);
-    if(!ludp->lud_attrs[i])
-      return FALSE;
-    ludp->lud_attrs_dups++;
-  }
-
   return (TRUE);
 }
 
@@ -767,22 +768,73 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
   if(!p)
     goto success;
 
-  /* parse attributes. skip "??".
-   */
+  /* Parse the attributes. skip "??" */
   q = strchr(p, '?');
   if(q)
     *q++ = '\0';
 
-  if(*p && *p != '?') {
-    ludp->lud_attrs = split_str(p);
+  if(*p) {
+    char **attributes;
+    size_t count = 0;
+
+    /* Split the string into an array of attributes */
+    if(!split_str(p, &attributes, &count)) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+    /* Allocate our array (+1 for the NULL entry) */
+#if defined(CURL_LDAP_WIN) && \
+    (defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI))
+    ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *));
+#else
+    ludp->lud_attrs = calloc(count + 1, sizeof(char *));
+#endif
     if(!ludp->lud_attrs) {
+      Curl_safefree(attributes);
+
       rc = LDAP_NO_MEMORY;
 
       goto quit;
     }
 
-    for(i = 0; ludp->lud_attrs[i]; i++)
-      LDAP_TRACE (("attr[%d] '%s'\n", i, ludp->lud_attrs[i]));
+    for(i = 0; i < count; i++) {
+      char *unescapped;
+
+      LDAP_TRACE (("attr[%d] '%s'\n", i, attributes[i]));
+
+      /* Unescape the attribute */
+      unescapped = curl_easy_unescape(conn->data, attributes[i], 0, NULL);
+      if(!unescapped) {
+        Curl_safefree(attributes);
+
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+
+#if defined(CURL_LDAP_WIN) && \
+    (defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI))
+      /* Convert the unescapped string to a tchar */
+      ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescapped);
+
+      /* Free the unescapped string as we are done with it */
+      Curl_unicodefree(unescapped);
+
+      if(!ludp->lud_attrs[i]) {
+        Curl_safefree(attributes);
+
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+#else
+      ludp->lud_attrs[i] = unescapped;
+#endif
+
+      ludp->lud_attrs_dups++;
+    }
   }
 
   p = q;