mirror of
https://github.com/samba-team/samba.git
synced 2025-03-01 04:58:35 +03:00
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)
This commit is contained in:
parent
24c22aef90
commit
7779b1e000
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user