The branch, master has been updated via 3cf48ee05ae99fb99d1b7b7204f9b8c444907a4a (commit) via 598f78bd1f3c59cfdca91a590bd95298b7d28d9e (commit) via 80420745ff2998626a302b5f863db8364e858f8f (commit) from ae6af9ecbfce559a50d95853d6e66b8aa8788741 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 3cf48ee05ae99fb99d1b7b7204f9b8c444907a4a Author: Jelmer Vernooij <jel...@samba.org> Date: Thu Apr 23 17:46:54 2009 +0200 Fix push_codepoint function without iconv_convenience. commit 598f78bd1f3c59cfdca91a590bd95298b7d28d9e Author: Jelmer Vernooij <jel...@samba.org> Date: Thu Apr 23 16:03:19 2009 +0200 charcnv: Import push_codepoint(). commit 80420745ff2998626a302b5f863db8364e858f8f Author: Jelmer Vernooij <jel...@samba.org> Date: Thu Apr 23 15:24:38 2009 +0200 Add a new non-convenience version of push_codepoint. ----------------------------------------------------------------------- Summary of changes: lib/util/charset/charcnv.c | 4 ++- lib/util/charset/charset.h | 3 +- lib/util/charset/tests/iconv.c | 2 +- lib/util/charset/util_unistr.c | 13 +++++-- source3/lib/charcnv.c | 61 +++++++++++++++++++++++++++++++++ source4/lib/registry/patchfile_preg.c | 38 ++++++++++----------- source4/ntvfs/posix/pvfs_rename.c | 4 +- 7 files changed, 96 insertions(+), 29 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c index 94d47a9..a479f44 100644 --- a/lib/util/charset/charcnv.c +++ b/lib/util/charset/charcnv.c @@ -430,7 +430,7 @@ _PUBLIC_ codepoint_t next_codepoint_convenience(struct smb_iconv_convenience *ic return the number of bytes occupied by the CH_UNIX character, or -1 on failure */ -_PUBLIC_ ssize_t push_codepoint(struct smb_iconv_convenience *ic, +_PUBLIC_ ssize_t push_codepoint_convenience(struct smb_iconv_convenience *ic, char *str, codepoint_t c) { smb_iconv_t descriptor; @@ -478,3 +478,5 @@ _PUBLIC_ ssize_t push_codepoint(struct smb_iconv_convenience *ic, } return 5 - olen; } + + diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index 37c5aca..2c8aa41 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -151,11 +151,12 @@ ssize_t iconv_talloc(TALLOC_CTX *mem_ctx, extern struct smb_iconv_convenience *global_iconv_convenience; codepoint_t next_codepoint(const char *str, size_t *size); +ssize_t push_codepoint(char *str, codepoint_t c); /* codepoints */ codepoint_t next_codepoint_convenience(struct smb_iconv_convenience *ic, const char *str, size_t *size); -ssize_t push_codepoint(struct smb_iconv_convenience *ic, +ssize_t push_codepoint_convenience(struct smb_iconv_convenience *ic, char *str, codepoint_t c); codepoint_t toupper_m(codepoint_t val); codepoint_t tolower_m(codepoint_t val); diff --git a/lib/util/charset/tests/iconv.c b/lib/util/charset/tests/iconv.c index 091876f..e8d7bc1 100644 --- a/lib/util/charset/tests/iconv.c +++ b/lib/util/charset/tests/iconv.c @@ -288,7 +288,7 @@ static bool test_codepoint(struct torture_context *tctx, unsigned int codepoint) size_t size, size2; codepoint_t c; - size = push_codepoint(lp_iconv_convenience(tctx->lp_ctx), (char *)buf, codepoint); + size = push_codepoint_convenience(lp_iconv_convenience(tctx->lp_ctx), (char *)buf, codepoint); torture_assert(tctx, size != -1 || (codepoint >= 0xd800 && codepoint <= 0x10000), "Invalid Codepoint range"); diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c index ea2bfea..024dc70 100644 --- a/lib/util/charset/util_unistr.c +++ b/lib/util/charset/util_unistr.c @@ -444,7 +444,7 @@ _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src) c = tolower_m(c); - c_size = push_codepoint(iconv_convenience, dest+size, c); + c_size = push_codepoint_convenience(iconv_convenience, dest+size, c); if (c_size == -1) { talloc_free(dest); return NULL; @@ -490,7 +490,7 @@ _PUBLIC_ char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n) c = toupper_m(c); - c_size = push_codepoint(iconv_convenience, dest+size, c); + c_size = push_codepoint_convenience(iconv_convenience, dest+size, c); if (c_size == -1) { talloc_free(dest); return NULL; @@ -551,7 +551,7 @@ _PUBLIC_ void strlower_m(char *s) while (*s) { size_t c_size, c_size2; codepoint_t c = next_codepoint_convenience(iconv_convenience, s, &c_size); - c_size2 = push_codepoint(iconv_convenience, d, tolower_m(c)); + c_size2 = push_codepoint_convenience(iconv_convenience, d, tolower_m(c)); if (c_size2 > c_size) { DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n", c, tolower_m(c), (int)c_size, (int)c_size2)); @@ -590,7 +590,7 @@ _PUBLIC_ void strupper_m(char *s) while (*s) { size_t c_size, c_size2; codepoint_t c = next_codepoint_convenience(iconv_convenience, s, &c_size); - c_size2 = push_codepoint(iconv_convenience, d, toupper_m(c)); + c_size2 = push_codepoint_convenience(iconv_convenience, d, toupper_m(c)); if (c_size2 > c_size) { DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n", c, toupper_m(c), (int)c_size, (int)c_size2)); @@ -992,3 +992,8 @@ _PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size) { return next_codepoint_convenience(get_iconv_convenience(), str, size); } + +_PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c) +{ + return push_codepoint_convenience(get_iconv_convenience(), str, c); +} diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 374079c..eb794d8 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -1861,3 +1861,64 @@ codepoint_t next_codepoint(const char *str, size_t *size) /* no other length is valid */ return INVALID_CODEPOINT; } + +/* + push a single codepoint into a CH_UNIX string the target string must + be able to hold the full character, which is guaranteed if it is at + least 5 bytes in size. The caller may pass less than 5 bytes if they + are sure the character will fit (for example, you can assume that + uppercase/lowercase of a character will not add more than 1 byte) + + return the number of bytes occupied by the CH_UNIX character, or + -1 on failure +*/ +_PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c) +{ + smb_iconv_t descriptor; + uint8_t buf[4]; + size_t ilen, olen; + const char *inbuf; + + if (c < 128) { + *str = c; + return 1; + } + + lazy_initialize_conv(); + + descriptor = conv_handles[CH_UNIX][CH_UTF16LE]; + if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { + return -1; + } + + if (c < 0x10000) { + ilen = 2; + olen = 5; + inbuf = (char *)buf; + SSVAL(buf, 0, c); + smb_iconv(descriptor, &inbuf, &ilen, &str, &olen); + if (ilen != 0) { + return -1; + } + return 5 - olen; + } + + c -= 0x10000; + + buf[0] = (c>>10) & 0xFF; + buf[1] = (c>>18) | 0xd8; + buf[2] = c & 0xFF; + buf[3] = ((c>>8) & 0x3) | 0xdc; + + ilen = 4; + olen = 5; + inbuf = (char *)buf; + + smb_iconv(descriptor, &inbuf, &ilen, &str, &olen); + if (ilen != 0) { + return -1; + } + return 5 - olen; +} + + diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index e9801bb..30a9aea 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -27,27 +27,26 @@ struct preg_data { int fd; TALLOC_CTX *ctx; - struct smb_iconv_convenience *ic; }; -static WERROR preg_read_utf16(struct smb_iconv_convenience *ic, int fd, char *c) +static WERROR preg_read_utf16(int fd, char *c) { uint16_t v; if (read(fd, &v, 2) < 2) { return WERR_GENERAL_FAILURE; } - push_codepoint(ic, c, v); + push_codepoint(c, v); return WERR_OK; } -static WERROR preg_write_utf16(struct smb_iconv_convenience *ic, int fd, const char *string) +static WERROR preg_write_utf16(int fd, const char *string) { codepoint_t v; uint16_t i; size_t size; for (i = 0; i < strlen(string); i+=size) { - v = next_codepoint_convenience(ic, &string[i], &size); + v = next_codepoint(&string[i], &size); if (write(fd, &v, 2) < 2) { return WERR_GENERAL_FAILURE; } @@ -67,19 +66,19 @@ static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, struct preg_data *data = (struct preg_data *)_data; uint32_t buf; - preg_write_utf16(data->ic, data->fd, "["); - preg_write_utf16(data->ic, data->fd, key_name); - preg_write_utf16(data->ic, data->fd, ";"); - preg_write_utf16(data->ic, data->fd, value_name); - preg_write_utf16(data->ic, data->fd, ";"); + preg_write_utf16(data->fd, "["); + preg_write_utf16(data->fd, key_name); + preg_write_utf16(data->fd, ";"); + preg_write_utf16(data->fd, value_name); + preg_write_utf16(data->fd, ";"); SIVAL(&buf, 0, value_type); write(data->fd, &buf, sizeof(uint32_t)); - preg_write_utf16(data->ic, data->fd, ";"); + preg_write_utf16(data->fd, ";"); SIVAL(&buf, 0, value_data.length); write(data->fd, &buf, sizeof(uint32_t)); - preg_write_utf16(data->ic, data->fd, ";"); + preg_write_utf16(data->fd, ";"); write(data->fd, value_data.data, value_data.length); - preg_write_utf16(data->ic, data->fd, "]"); + preg_write_utf16(data->fd, "]"); return WERR_OK; } @@ -169,7 +168,6 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, write(data->fd, (uint8_t *)&preg_header,8); data->ctx = ctx; - data->ic = ic; *callbacks = talloc(ctx, struct reg_diff_callbacks); @@ -228,7 +226,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, while(1) { uint32_t value_type, length; - if (!W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr))) { + if (!W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr))) { break; } if (*buf_ptr != '[') { @@ -239,7 +237,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Get the path */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } @@ -248,7 +246,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Get the name */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < buf_size) { buf_ptr++; } @@ -265,7 +263,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < buf_size) { DEBUG(0, ("Error in PReg file.\n")); ret = WERR_GENERAL_FAILURE; @@ -279,7 +277,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, } /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < buf_size) { DEBUG(0, ("Error in PReg file.\n")); ret = WERR_GENERAL_FAILURE; @@ -297,7 +295,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, /* Check if delimiter is in place (whine if it isn't) */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(iconv_convenience, fd, buf_ptr)) && + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ']') && buf_ptr-buf < buf_size) { DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n", *buf_ptr, *buf_ptr)); diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 7f8eab5..0616d38 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -118,13 +118,13 @@ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, c1 = next_codepoint_convenience(iconv_convenience, p1, &c_size1); c2 = next_codepoint_convenience(iconv_convenience, p2, &c_size2); if (c2 == '?') { - d += push_codepoint(iconv_convenience, d, c1); + d += push_codepoint_convenience(iconv_convenience, d, c1); } else if (c2 == '*') { memcpy(d, p1, strlen(p1)); d += strlen(p1); break; } else { - d += push_codepoint(iconv_convenience, d, c2); + d += push_codepoint_convenience(iconv_convenience, d, c2); } p1 += c_size1; -- Samba Shared Repository