diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-12-16 09:20:34 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-12-16 09:20:34 +0000 |
commit | 7779b1e00022599f9b77dab7f5f983d930514f15 (patch) | |
tree | b1e860ce476e5b15993f5532d5c3a854f912e83e | |
parent | 24c22aef90d8534ee2d016b37b2b302f1367d106 (diff) | |
download | samba-7779b1e00022599f9b77dab7f5f983d930514f15.tar.gz samba-7779b1e00022599f9b77dab7f5f983d930514f15.tar.bz2 samba-7779b1e00022599f9b77dab7f5f983d930514f15.zip |
added support for big-endian ucs2 strings (as used by big-endian
msrpc).
this was easier than I expected!
(This used to be commit a0a51af6b746b1f82faaa49d33c17fea9d708fb0)
-rw-r--r-- | source4/include/charset.h | 4 | ||||
-rw-r--r-- | source4/lib/charcnv.c | 1 | ||||
-rw-r--r-- | source4/lib/iconv.c | 37 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_basic.c | 24 |
4 files changed, 52 insertions, 14 deletions
diff --git a/source4/include/charset.h b/source4/include/charset.h index 3b3e613fd3..daf10e23c1 100644 --- a/source4/include/charset.h +++ b/source4/include/charset.h @@ -20,9 +20,9 @@ */ /* this defines the charset types used in samba */ -typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4} charset_t; +typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4, CH_UCS2BE=5} charset_t; -#define NUM_CHARSETS 5 +#define NUM_CHARSETS 6 /* * for each charset we have a function that pulls from that charset to diff --git a/source4/lib/charcnv.c b/source4/lib/charcnv.c index 72277b4f2e..11b0e64dce 100644 --- a/source4/lib/charcnv.c +++ b/source4/lib/charcnv.c @@ -52,6 +52,7 @@ static const char *charset_name(charset_t ch) else if (ch == CH_DOS) ret = lp_dos_charset(); else if (ch == CH_DISPLAY) ret = lp_display_charset(); else if (ch == CH_UTF8) ret = "UTF8"; + else if (ch == CH_UCS2BE) ret = "UCS-2BE"; if (!ret || !*ret) ret = "ASCII"; return ret; diff --git a/source4/lib/iconv.c b/source4/lib/iconv.c index 2a0b013257..3f37583e39 100644 --- a/source4/lib/iconv.c +++ b/source4/lib/iconv.c @@ -45,16 +45,18 @@ * @sa Samba Developers Guide **/ -static size_t ascii_pull(void *,const char **, size_t *, char **, size_t *); -static size_t ascii_push(void *,const char **, size_t *, char **, size_t *); -static size_t utf8_pull(void *,const char **, size_t *, char **, size_t *); -static size_t utf8_push(void *,const char **, size_t *, char **, size_t *); +static size_t ascii_pull (void *,const char **, size_t *, char **, size_t *); +static size_t ascii_push (void *,const char **, size_t *, char **, size_t *); +static size_t utf8_pull (void *,const char **, size_t *, char **, size_t *); +static size_t utf8_push (void *,const char **, size_t *, char **, size_t *); static size_t ucs2hex_pull(void *,const char **, size_t *, char **, size_t *); static size_t ucs2hex_push(void *,const char **, size_t *, char **, size_t *); -static size_t iconv_copy(void *,const char **, size_t *, char **, size_t *); +static size_t iconv_copy (void *,const char **, size_t *, char **, size_t *); +static size_t iconv_swab (void *,const char **, size_t *, char **, size_t *); static struct charset_functions builtin_functions[] = { {"UCS-2LE", iconv_copy, iconv_copy}, + {"UCS-2BE", iconv_swab, iconv_swab}, {"UTF8", utf8_pull, utf8_push}, {"ASCII", ascii_pull, ascii_push}, {"UCS2-HEX", ucs2hex_pull, ucs2hex_push}, @@ -404,6 +406,31 @@ static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft, return 0; } +static size_t iconv_swab(void *cd, const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + int n; + + n = MIN(*inbytesleft, *outbytesleft); + + swab(*inbuf, *outbuf, (n&~1)); + if (n&1) { + (*outbuf)[n-1] = 0; + } + + (*inbytesleft) -= n; + (*outbytesleft) -= n; + (*inbuf) += n; + (*outbuf) += n; + + if (*inbytesleft > 0) { + errno = E2BIG; + return -1; + } + + return 0; +} + static size_t iconv_copy(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index ed75b8c27c..cde0b52f3b 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -344,11 +344,16 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) uint32 len1, ofs, len2; uint16 len3; int ret; + int chset = CH_UCS2; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } + if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { + chset = CH_UCS2BE; + } + switch (ndr->flags & LIBNDR_STRING_FLAGS) { case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4: case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM: @@ -365,7 +370,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) break; } NDR_PULL_NEED_BYTES(ndr, len2*2); - ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, ndr->data+ndr->offset, len2*2, (const void **)&as); @@ -384,7 +389,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) *s = talloc_strdup(ndr->mem_ctx, ""); break; } - ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, ndr->data+ndr->offset, len1*2, (const void **)&as); @@ -402,7 +407,7 @@ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s) if (len1*2+2 <= ndr->data_size - ndr->offset) { len1++; } - ret = convert_string_talloc(ndr->mem_ctx, CH_UCS2, CH_UNIX, + ret = convert_string_talloc(ndr->mem_ctx, chset, CH_UNIX, ndr->data+ndr->offset, len1*2, (const void **)s); @@ -461,10 +466,15 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) { ssize_t s_len, c_len; int ret; + int chset = CH_UCS2; if (!(ndr_flags & NDR_SCALARS)) { return NT_STATUS_OK; } + + if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) { + chset = CH_UCS2BE; + } s_len = s?strlen(s):0; c_len = s?strlen_m(s):0; @@ -475,7 +485,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) NDR_CHECK(ndr_push_uint32(ndr, 0)); NDR_CHECK(ndr_push_uint32(ndr, c_len+1)); NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2); - ret = convert_string(CH_UNIX, CH_UCS2, + ret = convert_string(CH_UNIX, chset, s, s_len+1, ndr->data+ndr->offset, c_len*2 + 2); if (ret == -1) { @@ -490,7 +500,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) NDR_CHECK(ndr_push_uint32(ndr, 0)); NDR_CHECK(ndr_push_uint32(ndr, c_len)); NDR_PUSH_NEED_BYTES(ndr, c_len*2); - ret = convert_string(CH_UNIX, CH_UCS2, + ret = convert_string(CH_UNIX, chset, s, s_len, ndr->data+ndr->offset, c_len*2); if (ret == -1) { @@ -503,7 +513,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) case LIBNDR_FLAG_STR_SIZE4: NDR_CHECK(ndr_push_uint32(ndr, c_len + 1)); NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2); - ret = convert_string(CH_UNIX, CH_UCS2, + ret = convert_string(CH_UNIX, chset, s, s_len + 1, ndr->data+ndr->offset, c_len*2 + 2); if (ret == -1) { @@ -515,7 +525,7 @@ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s) case LIBNDR_FLAG_STR_NULLTERM: NDR_PUSH_NEED_BYTES(ndr, c_len*2 + 2); - ret = convert_string(CH_UNIX, CH_UCS2, + ret = convert_string(CH_UNIX, chset, s, s_len+1, ndr->data+ndr->offset, c_len*2 + 2); if (ret == -1) { |