summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/charcnv.c48
-rw-r--r--source3/lib/util.c5
-rw-r--r--source3/lib/util_unistr.c45
-rw-r--r--source3/smbd/mangle.c41
4 files changed, 98 insertions, 41 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index 59a2af72a4..5ed31d2a4c 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -4,6 +4,7 @@
Character set conversion Extensions
Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Simo Sorce 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -150,7 +151,7 @@ size_t convert_string_allocate(charset_t from, charset_t to,
{
size_t i_len, o_len, destlen;
size_t retval;
- char* inbuf = (char *)src;
+ char *inbuf = (char *)src;
char *outbuf, *ob;
smb_iconv_t descriptor;
@@ -178,7 +179,7 @@ convert:
ob = (char *)realloc(outbuf, destlen);
if (!ob) {
DEBUG(0, ("convert_string_allocate: realloc failed!\n"));
- free(outbuf);
+ SAFE_FREE(outbuf);
return -1;
}
else outbuf = ob;
@@ -208,10 +209,11 @@ convert:
}
destlen = destlen - o_len;
+ *dest = (char *)realloc(ob,destlen);
*dest = (char *)realloc(outbuf,destlen);
if (!*dest) {
DEBUG(0, ("convert_string_allocate: out of memory!\n"));
- free(outbuf);
+ SAFE_FREE(ob);
return -1;
}
@@ -491,14 +493,14 @@ char *acnv_u2ux(const smb_ucs2_t *src)
size_t dlen;
void *dest;
- slen = strlen_w(src) + 1;
+ slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t);
dlen = convert_string_allocate(CH_UCS2, CH_UNIX, src, slen, &dest);
if (dlen == -1) return NULL;
else return dest;
}
/****************************************************************************
-convert from ucs2 to unix charset and return the
+convert from unix to ucs2 charset and return the
allocated and converted string or NULL if an error occurred.
you must provide a zero terminated string.
the returning string will be zero terminated.
@@ -514,3 +516,39 @@ smb_ucs2_t *acnv_uxu2(const char *src)
if (dlen == -1) return NULL;
else return dest;
}
+
+/****************************************************************************
+convert from ucs2 to dos charset and return the
+allocated and converted string or NULL if an error occurred.
+you must provide a zero terminated string.
+the returning string will be zero terminated.
+****************************************************************************/
+char *acnv_u2dos(const smb_ucs2_t *src)
+{
+ size_t slen;
+ size_t dlen;
+ void *dest;
+
+ slen = (strlen_w(src) + 1) * sizeof(smb_ucs2_t);
+ dlen = convert_string_allocate(CH_UCS2, CH_DOS, src, slen, &dest);
+ if (dlen == -1) return NULL;
+ else return dest;
+}
+
+/****************************************************************************
+convert from dos to ucs2 charset and return the
+allocated and converted string or NULL if an error occurred.
+you must provide a zero terminated string.
+the returning string will be zero terminated.
+****************************************************************************/
+smb_ucs2_t *acnv_dosu2(const char *src)
+{
+ size_t slen;
+ size_t dlen;
+ void *dest;
+
+ slen = strlen(src) + 1;
+ dlen = convert_string_allocate(CH_DOS, CH_UCS2, src, slen, &dest);
+ if (dlen == -1) return NULL;
+ else return dest;
+}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index e2a5fe10d0..02397dd4c4 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -4,6 +4,7 @@
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 2001
+ Copyright (C) Simo Sorce 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -429,7 +430,7 @@ smb_ucs2_t *unix_clean_path(const smb_ucs2_t *s)
smb_ucs2_t *ns;
smb_ucs2_t *p, *r, *t;
- DEBUG(3, ("unix_clean_name_w\n")); /* [%unicode]\n")); */
+ DEBUG(3, ("unix_clean_path\n")); /* [%unicode]\n")); */
/* convert '\' to '/' */
ns = strdup_w(s);
@@ -450,7 +451,7 @@ smb_ucs2_t *unix_clean_path(const smb_ucs2_t *s)
/* reduce any /../ */
t = ns;
- while ((r = strstr_wa(t, "/..")) != NULL) {
+ while ((r = strstr_wa(t, "/.."))) {
t = &(r[3]);
if (*t == UCS2_CHAR('/') || *t == 0) {
*r = 0;
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 08281fec4f..58ecc19723 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -231,6 +231,18 @@ size_t strlen_w(const smb_ucs2_t *src)
}
/*******************************************************************
+ Count up to max number of characters in a smb_ucs2_t string.
+********************************************************************/
+size_t strnlen_w(const smb_ucs2_t *src, size_t max)
+{
+ size_t len;
+
+ for(len = 0; *src++ && (len < max); len++) ;
+
+ return len;
+}
+
+/*******************************************************************
wide strchr()
********************************************************************/
smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
@@ -440,8 +452,7 @@ smb_ucs2_t *strncat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, const size_t max)
if (!dest || !src) return NULL;
start = strlen_w(dest);
- len = strlen_w(src);
- if (len > max) len = max;
+ len = strnlen_w(src, max);
memcpy(&dest[start], src, len*sizeof(smb_ucs2_t));
dest[start+len] = 0;
@@ -465,7 +476,6 @@ smb_ucs2_t *strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src)
return dest;
}
-
/*******************************************************************
replace any occurence of oldc with newc in unicode string
********************************************************************/
@@ -595,6 +605,35 @@ smb_ucs2_t *strncpy_wa(smb_ucs2_t *dest, const char *src, const size_t max)
}
/*******************************************************************
+convert and duplicate an ascii string
+********************************************************************/
+smb_ucs2_t *strdup_wa(const char *src)
+{
+ return strndup_wa(src, 0);
+}
+
+/* if len == 0 then duplicate the whole string */
+smb_ucs2_t *strndup_wa(const char *src, size_t len)
+{
+ smb_ucs2_t *dest, *s;
+
+ s = acnv_dosu2(src);
+ if (!len) len = strlen_w(s);
+ dest = (smb_ucs2_t *)malloc((len + 1) * sizeof(smb_ucs2_t));
+ if (!dest) {
+ DEBUG(0,("strdup_w: out of memory!\n"));
+ SAFE_FREE(s);
+ return NULL;
+ }
+
+ memcpy(dest, src, len * sizeof(smb_ucs2_t));
+ dest[len] = 0;
+
+ SAFE_FREE(s);
+ return dest;
+}
+
+/*******************************************************************
append a string of len bytes and add a terminator
********************************************************************/
diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c
index 44ffd155e4..1b7f9d0c05 100644
--- a/source3/smbd/mangle.c
+++ b/source3/smbd/mangle.c
@@ -437,13 +437,12 @@ smb_ucs2_t *mangle(const smb_ucs2_t *unmangled)
}
else /* FOUND */
{
- p = (smb_ucs2_t *)malloc(data.dsize*sizeof(smb_ucs2_t));
+ p = acnv_dosu2(data.dptr);
if (!p)
{
DEBUG(0,("mangle: out of memory!\n"));
goto done;
}
- dos_to_ucs2(p, data.dptr, data.dsize*sizeof(smb_ucs2_t));
}
if (ext)
@@ -491,18 +490,15 @@ char *dos_mangle(const char *dos_unmangled)
{
smb_ucs2_t *in, *out;
char *dos_mangled;
- size_t len;
if (!dos_unmangled || !*dos_unmangled) return NULL;
- len = (strlen(dos_unmangled) + 1) * sizeof(smb_ucs2_t);
- in = (smb_ucs2_t *)malloc(len);
+ in = acnv_dosu2(dos_unmangled);
if (!in)
{
DEBUG(0,("dos_mangle: out of memory!\n"));
return NULL;
}
- dos_to_ucs2(in, dos_unmangled, len);
out = mangle(in);
if (!out)
@@ -511,13 +507,12 @@ char *dos_mangle(const char *dos_unmangled)
return NULL;
}
- dos_mangled = (char *)malloc(PSTRING_LEN);
+ dos_mangled = acnv_u2dos(out);
if (!dos_mangled)
{
DEBUG(0,("dos_mangle: out of memory!\n"));
goto done;
}
- ucs2_to_dos (dos_mangled, out, PSTRING_LEN);
done:
SAFE_FREE(in);
@@ -529,18 +524,15 @@ char *dos_unmangle(const char *dos_mangled)
{
smb_ucs2_t *in, *out;
char *dos_unmangled;
- size_t len;
if (!dos_mangled || !*dos_mangled) return NULL;
- len = (strlen(dos_mangled) + 1) * sizeof(smb_ucs2_t);
- in = (smb_ucs2_t *)malloc(len);
+ in = acnv_dosu2(dos_mangled);
if (!in)
{
DEBUG(0,("dos_unmangle: out of memory!\n"));
return NULL;
}
- dos_to_ucs2(in, dos_mangled, len);
out = mangle(in);
if (!out)
@@ -549,13 +541,12 @@ char *dos_unmangle(const char *dos_mangled)
return NULL;
}
- dos_unmangled = (char *)malloc(PSTRING_LEN);
+ dos_unmangled = acnv_u2dos(out);
if (!dos_unmangled)
{
DEBUG(0,("dos_unmangle: out of memory!\n"));
goto done;
}
- ucs2_to_dos (dos_unmangled, out, PSTRING_LEN);
done:
SAFE_FREE(in);
@@ -574,14 +565,13 @@ BOOL is_8_3(const char *fname, BOOL check_case)
if (strlen(fname) > 12) return False;
- ucs2name = (smb_ucs2_t *)malloc(13 * sizeof(smb_ucs2_t));
+ ucs2name = acnv_uxu2(fname);
if (!ucs2name)
{
DEBUG(0,("is_8_3: out of memory!\n"));
goto done;
}
- push_ucs2(NULL, ucs2name, fname, 13, STR_TERMINATE);
ret = is_8_3_w(ucs2name);
done:
@@ -650,7 +640,7 @@ NTSTATUS is_valid_name(const smb_ucs2_t *fname)
if (!fname || !*fname) return NT_STATUS_INVALID_PARAMETER;
- DEBUG(10,("has_valid_chars: testing\n")); /* [%s]\n", s)); */
+ DEBUG(10,("is_valid_name: testing\n")); /* [%s]\n", s)); */
ret = has_valid_chars(fname);
if (NT_STATUS_IS_ERR(ret)) return ret;
@@ -703,7 +693,6 @@ NTSTATUS is_valid_name(const smb_ucs2_t *fname)
BOOL is_mangled(const char *s)
{
smb_ucs2_t *u2, *res;
- size_t u2len;
BOOL ret = False;
DEBUG(10,("is_mangled: testing [%s]\n", s));
@@ -711,14 +700,12 @@ BOOL is_mangled(const char *s)
if (!s || !*s) return False;
if ((strlen(s) > 12) || (!strchr(s, '~'))) return False;
- u2len = (strlen(s) + 1) * sizeof(smb_ucs2_t);
- u2 = (smb_ucs2_t *)malloc(u2len);
+ u2 = acnv_dosu2(s);
if (!u2)
{
DEBUG(0,("is_mangled: out of memory!\n"));
return ret;
}
- dos_to_ucs2(u2, s, u2len);
res = unmangle(u2);
if (res) ret = True;
@@ -774,7 +761,6 @@ void reset_mangled_cache(void)
BOOL check_mangled_cache(char *s)
{
smb_ucs2_t *u2, *res;
- size_t slen, u2len;
BOOL ret = False;
DEBUG(10,("check_mangled_cache: I'm so ugly, please remove me!\n"));
@@ -782,15 +768,12 @@ BOOL check_mangled_cache(char *s)
if (!s || !*s) return False;
- slen = strlen(s);
- u2len = (slen + 1) * sizeof(smb_ucs2_t);
- u2 = (smb_ucs2_t *)malloc(u2len);
+ u2 = acnv_dosu2(s);
if (!u2)
{
DEBUG(0,("check_mangled_cache: out of memory!\n"));
return ret;
}
- dos_to_ucs2(u2, s, u2len);
res = unmangle(u2);
if (res)
@@ -814,22 +797,18 @@ BOOL check_mangled_cache(char *s)
void mangle_name_83(char *s)
{
smb_ucs2_t *u2, *res;
- size_t slen, u2len;
DEBUG(10,("mangle_name_83: I'm so ugly, please remove me!\n"));
DEBUG(10,("mangle_name_83: testing -> [%s]\n", s));
if (!s || !*s) return;
- slen = strlen(s);
- u2len = (slen + 1) * sizeof(smb_ucs2_t);
- u2 = (smb_ucs2_t *)malloc(u2len);
+ u2 = acnv_dosu2(s);
if (!u2)
{
DEBUG(0,("mangle_name_83: out of memory!\n"));
return;
}
- dos_to_ucs2(u2, s, u2len);
res = mangle(u2);
if (res) ucs2_to_dos (s, res, 13); /* ugly, but must be done this way */