summaryrefslogtreecommitdiff
path: root/source3/lib/charcnv.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-07-13 01:22:09 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:28:35 -0500
commite8dc2ea03d212bc4b4facc2a900f6a443365c390 (patch)
treec418222494cb9cd05250f30b8f6671e0b3046fa3 /source3/lib/charcnv.c
parent79a9f6dcb86703fd48d1321e50ff2b678ce39664 (diff)
downloadsamba-e8dc2ea03d212bc4b4facc2a900f6a443365c390.tar.gz
samba-e8dc2ea03d212bc4b4facc2a900f6a443365c390.tar.bz2
samba-e8dc2ea03d212bc4b4facc2a900f6a443365c390.zip
r23858: Added srvstr_pull_buf_talloc() and srvstr_pull_talloc()
calls and converted reply_tcon and reply_tconX to use them - to show the boilerplate usage (valgrind tested). In conjunction with Volker's srvstr_get_path_talloc() work this should allow us to start eliminating all pstrings/fstrings out of the main path processing code. I'll watch the build farm tonight... Jeremy. (This used to be commit b4eff3f68089f082781afcf90d43faa317949566)
Diffstat (limited to 'source3/lib/charcnv.c')
-rw-r--r--source3/lib/charcnv.c250
1 files changed, 234 insertions, 16 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index b48880a8ea..b71e15f44d 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -1,21 +1,21 @@
-/*
+/*
Unix SMB/CIFS implementation.
Character set conversion Extensions
Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
Copyright (C) Andrew Tridgell 2001
Copyright (C) Simo Sorce 2001
Copyright (C) Martin Pool 2003
-
+
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -33,7 +33,7 @@ char lp_failed_convert_char(void)
* @file
*
* @brief Character-set conversion routines built on our iconv.
- *
+ *
* @note Samba's internal character set (at least in the 3.0 series)
* is always the same as the one for the Unix filesystem. It is
* <b>not</b> necessarily UTF-8 and may be different on machines that
@@ -509,6 +509,7 @@ size_t convert_string(charset_t from, charset_t to,
* Convert between character sets, allocating a new buffer for the result.
*
* @param ctx TALLOC_CTX to use to allocate with. If NULL use malloc.
+ * (this is a bad interface and needs fixing. JRA).
* @param srclen length of source buffer.
* @param dest always set at least to NULL
* @note -1 is not accepted for srclen.
@@ -516,7 +517,7 @@ size_t convert_string(charset_t from, charset_t to,
* @returns Size in bytes of the converted string; or -1 in case of error.
*
* Ensure the srclen contains the terminating zero.
- *
+ *
* I hate the goto's in this function. It's embarressing.....
* There has to be a cleaner way to do this. JRA.
**/
@@ -603,6 +604,11 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
if (!conv_silent)
DEBUG(0,("Conversion error: %s(%s)\n",reason,inbuf));
/* smb_panic(reason); */
+ if (ctx) {
+ TALLOC_FREE(ob);
+ } else {
+ SAFE_FREE(ob);
+ }
return (size_t)-1;
}
@@ -711,7 +717,7 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
* Convert between character sets, allocating a new buffer using talloc for the result.
*
* @param srclen length of source buffer.
- * @param dest always set at least to NULL
+ * @param dest always set at least to NULL
* @note -1 is not accepted for srclen.
*
* @returns Size in bytes of the converted string; or -1 in case of error.
@@ -736,7 +742,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
{
size_t size;
smb_ucs2_t *buffer;
-
+
size = push_ucs2_allocate(&buffer, src);
if (size == (size_t)-1) {
smb_panic("failed to create UCS2 buffer");
@@ -745,7 +751,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
free(buffer);
return srclen;
}
-
+
size = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, True);
free(buffer);
return size;
@@ -788,7 +794,7 @@ char *strdup_upper(const char *s)
}
strupper_w(buffer);
-
+
size = convert_string(CH_UTF16LE, CH_UNIX, buffer, -1, out_buffer, sizeof(out_buffer), True);
if (size == (size_t)-1) {
return NULL;
@@ -802,7 +808,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
{
size_t size;
smb_ucs2_t *buffer = NULL;
-
+
size = convert_string_allocate(NULL, CH_UNIX, CH_UTF16LE, src, srclen,
(void **)(void *)&buffer, True);
if (size == (size_t)-1 || !buffer) {
@@ -826,21 +832,21 @@ char *strdup_lower(const char *s)
size_t size;
smb_ucs2_t *buffer = NULL;
char *out_buffer;
-
+
size = push_ucs2_allocate(&buffer, s);
if (size == -1 || !buffer) {
return NULL;
}
strlower_w(buffer);
-
+
size = pull_ucs2_allocate(&out_buffer, buffer);
SAFE_FREE(buffer);
if (size == (size_t)-1) {
return NULL;
}
-
+
return out_buffer;
}
@@ -987,6 +993,84 @@ size_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len,
return src_len;
}
+/**
+ * Copy a string from a dos codepage source to a unix char* destination.
+ Talloc version.
+ Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
+ needs fixing. JRA).
+ *
+ * The resulting string in "dest" is always null terminated.
+ *
+ * @param flags can have:
+ * <dl>
+ * <dt>STR_TERMINATE</dt>
+ * <dd>STR_TERMINATE means the string in @p src
+ * is null terminated, and src_len is ignored.</dd>
+ * </dl>
+ *
+ * @param src_len is the length of the source area in bytes.
+ * @returns the number of bytes occupied by the string in @p src.
+ **/
+
+static size_t pull_ascii_base_talloc(TALLOC_CTX *ctx,
+ char **ppdest,
+ const void *src,
+ size_t src_len,
+ int flags)
+{
+ char *dest = NULL;
+ size_t dest_len = 0;
+
+#ifdef DEVELOPER
+ /* Ensure we never use the braindead "malloc" varient. */
+ if (ctx == NULL) {
+ smb_panic("NULL talloc CTX in pull_ascii_base_talloc\n");
+ }
+#endif
+
+ *ppdest = NULL;
+
+ if (flags & STR_TERMINATE) {
+ if (src_len == (size_t)-1) {
+ src_len = strlen((const char *)src) + 1;
+ } else {
+ size_t len = strnlen((const char *)src, src_len);
+ if (len < src_len)
+ len++;
+ src_len = len;
+ }
+ /* Ensure we don't use an insane length from the client. */
+ if (src_len >= 1024*1024) {
+ smb_panic("Bad src length in pull_ascii_base_talloc\n");
+ }
+ }
+
+ dest_len = convert_string_allocate(ctx,
+ CH_DOS,
+ CH_UNIX,
+ src,
+ src_len,
+ &dest,
+ True);
+
+ if (dest_len == (size_t)-1) {
+ return 0;
+ }
+
+ if (dest_len && dest) {
+ /* Did we already process the terminating zero ? */
+ if (dest[dest_len-1] != 0) {
+ dest[dest_len-1] = 0;
+ }
+ } else if (dest) {
+ dest[0] = 0;
+ }
+
+ *ppdest = dest;
+ return src_len;
+}
+
+
size_t pull_ascii_pstring(char *dest, const void *src)
{
return pull_ascii(dest, src, sizeof(pstring), -1, STR_TERMINATE);
@@ -1214,7 +1298,7 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_
/* ucs2 is always a multiple of 2 bytes */
if (src_len != (size_t)-1)
src_len &= ~1;
-
+
ret = convert_string(CH_UTF16LE, CH_UNIX, src, src_len, dest, dest_len, True);
if (ret == (size_t)-1) {
return 0;
@@ -1222,7 +1306,7 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_
if (src_len == (size_t)-1)
src_len = ret*2;
-
+
if (dest_len && ret) {
/* Did we already process the terminating zero ? */
if (dest[MIN(ret-1, dest_len-1)] != 0) {
@@ -1235,6 +1319,92 @@ size_t pull_ucs2(const void *base_ptr, char *dest, const void *src, size_t dest_
return src_len;
}
+/**
+ Copy a string from a ucs2 source to a unix char* destination.
+ Talloc version with a base pointer.
+ Uses malloc if TALLOC_CTX is NULL (this is a bad interface and
+ needs fixing. JRA).
+ Flags can have:
+ STR_TERMINATE means the string in src is null terminated.
+ STR_NOALIGN means don't try to align.
+ if STR_TERMINATE is set then src_len is ignored if it is -1.
+ src_len is the length of the source area in bytes
+ Return the number of bytes occupied by the string in src.
+ The resulting string in "dest" is always null terminated.
+**/
+
+static size_t pull_ucs2_base_talloc(TALLOC_CTX *ctx,
+ const void *base_ptr,
+ char **ppdest,
+ const void *src,
+ size_t src_len,
+ int flags)
+{
+ char *dest;
+ size_t dest_len;
+
+ *ppdest = NULL;
+
+#ifdef DEVELOPER
+ /* Ensure we never use the braindead "malloc" varient. */
+ if (ctx == NULL) {
+ smb_panic("NULL talloc CTX in pull_ucs2_base_talloc\n");
+ }
+#endif
+
+ if (ucs2_align(base_ptr, src, flags)) {
+ src = (const void *)((const char *)src + 1);
+ if (src_len != (size_t)-1)
+ src_len--;
+ }
+
+ if (flags & STR_TERMINATE) {
+ /* src_len -1 is the default for null terminated strings. */
+ if (src_len != (size_t)-1) {
+ size_t len = strnlen_w((const smb_ucs2_t *)src,
+ src_len/2);
+ if (len < src_len/2)
+ len++;
+ src_len = len*2;
+ }
+ /* Ensure we don't use an insane length from the client. */
+ if (src_len >= 1024*1024) {
+ smb_panic("Bad src length in pull_ucs2_base_talloc\n");
+ }
+ }
+
+ /* ucs2 is always a multiple of 2 bytes */
+ if (src_len != (size_t)-1) {
+ src_len &= ~1;
+ }
+
+ dest_len = convert_string_talloc(ctx,
+ CH_UTF16LE,
+ CH_UNIX,
+ src,
+ src_len,
+ (void **)&dest,
+ True);
+ if (dest_len == (size_t)-1) {
+ return 0;
+ }
+
+ if (src_len == (size_t)-1)
+ src_len = dest_len*2;
+
+ if (dest_len) {
+ /* Did we already process the terminating zero ? */
+ if (dest[dest_len-1] != 0) {
+ dest[dest_len-1] = 0;
+ }
+ } else if (dest) {
+ dest[0] = 0;
+ }
+
+ *ppdest = dest;
+ return src_len;
+}
+
size_t pull_ucs2_pstring(char *dest, const void *src)
{
return pull_ucs2(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE);
@@ -1398,6 +1568,54 @@ size_t pull_string_fn(const char *function, unsigned int line,
return pull_ascii(dest, src, dest_len, src_len, flags);
}
+/**
+ Copy a string from a unicode or ascii source (depending on
+ the packet flags) to a char* destination.
+ Variant that uses talloc.
+ Flags can have:
+ STR_TERMINATE means the string in src is null terminated.
+ STR_UNICODE means to force as unicode.
+ STR_ASCII use ascii even with unicode packet.
+ STR_NOALIGN means don't do alignment.
+ if STR_TERMINATE is set then src_len is ignored is it is -1
+ src_len is the length of the source area in bytes.
+ Return the number of bytes occupied by the string in src.
+ The resulting string in "dest" is always null terminated.
+**/
+
+size_t pull_string_talloc_fn(const char *function,
+ unsigned int line,
+ TALLOC_CTX *ctx,
+ const void *base_ptr,
+ uint16 smb_flags2,
+ char **ppdest,
+ const void *src,
+ size_t src_len,
+ int flags)
+{
+ if ((base_ptr == NULL) && ((flags & (STR_ASCII|STR_UNICODE)) == 0)) {
+ smb_panic("No base ptr to get flg2 and neither ASCII nor "
+ "UNICODE defined");
+ }
+
+ if (!(flags & STR_ASCII) && \
+ ((flags & STR_UNICODE || \
+ (smb_flags2 & FLAGS2_UNICODE_STRINGS)))) {
+ return pull_ucs2_base_talloc(ctx,
+ base_ptr,
+ ppdest,
+ src,
+ src_len,
+ flags);
+ }
+ return pull_ascii_base_talloc(ctx,
+ ppdest,
+ src,
+ src_len,
+ flags);
+}
+
+
size_t align_string(const void *base_ptr, const char *p, int flags)
{
if (!(flags & STR_ASCII) && \