[bug] the last char of multibyte string may not be correctly shown
Samba-JP TAKAHASHI Motonobu
monyo at samba.gr.jp
Mon Jun 25 16:59:48 GMT 2001
Hello
The following problem was found at Samba-JP.
If a multibyte character is the last char(not byte) of a string, only
the 1st byte of the char may be displayed.
For example there is a string named "s",
0xb4c1bbfa (means "KANJI" in Kanji character of EUC code)
and display with
printf("%-3.3s", s);
then only the 1st byte (0xbb) of the last char (0xbbfa) is displayed
and this becomes a broken character in Japanese.
Here is a big patch to fix it for Samba HEAD branch at 21st June.
---- Cut Here for HEAD ----
diff -urNP ../../samba-head/source/rpcclient/display.c ./rpcclient/display.c
--- ../../samba-head/source/rpcclient/display.c Wed Aug 2 03:32:34 2000
+++ ./rpcclient/display.c Thu Jun 21 14:10:44 2001
@@ -1206,13 +1206,18 @@
static void print_reg_value(FILE *out_hnd, char *val_name, uint32 val_type, BUFFER2 *value)
{
fstring type;
+ pstring name;
+
fstrcpy(type, get_reg_val_type_str(val_type));
+ pstrcpy(name, dos_to_unix(val_name, False));
+ val_name = name;
switch (val_type)
{
case 0x01: /* unistr */
{
- fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_str(value));
+ fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type,
+ dos_to_unix(dos_buffer2_to_str(value), False));
break;
}
@@ -1234,13 +1239,15 @@
case 0x04: /* uint32 */
{
- fprintf(out_hnd,"\t%s:\t%s: 0x%08x\n", val_name, type, buffer2_to_uint32(value));
+ fprintf(out_hnd,"\t%s:\t%s: 0x%08x\n", val_name, type,
+ buffer2_to_uint32(value));
break;
}
case 0x07: /* multiunistr */
{
- fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_multistr(value));
+ fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type,
+ dos_to_unix(dos_buffer2_to_multistr(value), False));
break;
}
}
diff -ur client/client.c.010622 client/client.c
--- client/client.c.010622 Tue May 8 14:13:38 2001
+++ client/client.c Fri Jun 22 15:04:12 2001
@@ -1546,6 +1546,7 @@
static void browse_fn(const char *name, uint32 m, const char *comment)
{
fstring typestr;
+ pstring s;
*typestr=0;
@@ -1561,8 +1562,8 @@
fstrcpy(typestr,"IPC"); break;
}
- printf("\t%-15.15s%-10.10s%s\n",
- name, typestr,comment);
+ dos_to_unix(s, strncpy_fill(s, unix_to_dos(s, name), 15));
+ printf("\t%s%-10.10s%s\n", s, typestr, comment);
}
@@ -1587,7 +1588,10 @@
****************************************************************************/
static void server_fn(const char *name, uint32 m, const char *comment)
{
- printf("\t%-16.16s %s\n", name, comment);
+ pstring s;
+
+ dos_to_unix(s, strncpy_fill(s, unix_to_dos(s, name), 16));
+ printf("\t%s %s\n", s, comment);
}
/****************************************************************************
diff -ur include/proto.h.010622 include/proto.h
--- include/proto.h.010622 Fri Jun 22 14:54:37 2001
+++ include/proto.h Fri Jun 22 14:57:14 2001
@@ -404,6 +404,7 @@
char *safe_strcat(char *dest, const char *src, size_t maxlength);
char *alpha_strcpy(char *dest, const char *src, size_t maxlength);
char *StrnCpy(char *dest,const char *src,size_t n);
+char *strncpy_fill(char *dest, const char *src, size_t n);
char *strncpyn(char *dest, const char *src,size_t n, char c);
size_t strhex_to_str(char *p, size_t len, const char *strhex);
BOOL in_list(char *s,char *list,BOOL casesensitive);
diff -ur lib/util.c.010622 lib/util.c
--- lib/util.c.010622 Wed Jun 13 13:19:00 2001
+++ lib/util.c Fri Jun 22 15:08:23 2001
@@ -301,8 +301,11 @@
(void)memset( buf, 0, 20 );
if (strcmp(In,"*") == 0)
buf[0] = '*';
- else
- (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
+ else {
+ strncpy_fill(buf, In, 15);
+ buf[15] = name_type;
+ buf[16] = '\0';
+ }
/* Place the length of the first field into the output buffer. */
p[0] = 32;
diff -ur lib/util_str.c.010622 lib/util_str.c
--- lib/util_str.c.010622 Fri Jun 15 17:33:37 2001
+++ lib/util_str.c Fri Jun 22 15:34:27 2001
@@ -1166,11 +1166,46 @@
n -= skip;
while (skip--) *d++ = *src++;
} else {
- n--;
- *d++ = *src++;
+ n--;
+ *d++ = *src++;
}
}
}
+ *d = 0;
+ return(dest);
+}
+
+/****************************************************************************
+ Like strncpy but always spaces fill the rest. Make sure there is room!
+ The variable n should always be one less than the available size.
+****************************************************************************/
+
+char *strncpy_fill(char *dest, const char *src, size_t n)
+{
+ size_t skip;
+ char *d = dest;
+
+ if (!dest) {
+ return(NULL);
+ }
+
+ if (!src);
+ else if(!global_is_multibyte_codepage) {
+ while (n-- && *src) *d++ = *src++;
+ } else {
+ while (n && *src) {
+ skip = get_character_len( *src );
+ if( skip != 0 ) {
+ if (skip > n) break;
+ n -= skip;
+ while (skip--) *d++ = *src++;
+ } else {
+ n--;
+ *d++ = *src++;
+ }
+ }
+ }
+ while (n--) *d++ = ' ';
*d = 0;
return(dest);
}
diff -ur libsmb/nmblib.c.010622 libsmb/nmblib.c
--- libsmb/nmblib.c.010622 Fri May 4 04:11:43 2001
+++ libsmb/nmblib.c Fri Jun 22 15:09:54 2001
@@ -279,7 +279,9 @@
buf1[0] = '*';
buf1[15] = name->name_type;
} else {
- slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type);
+ strncpy_fill(buf1, name->name, 15);
+ buf[15] = name->name_type;
+ buf[16] = '\0';
}
buf[offset] = 0x20;
diff -ur nmbd/nmbd_incomingrequests.c.010622 nmbd/nmbd_incomingrequests.c
--- nmbd/nmbd_incomingrequests.c.010622 Wed May 10 23:28:47 2000
+++ nmbd/nmbd_incomingrequests.c Fri Jun 22 15:17:04 2001
@@ -368,7 +368,7 @@
{
/* Start with the name. */
memset(buf,'\0',18);
- slprintf(buf, 17, "%-15.15s",namerec->name.name);
+ strncpy_fill(buf, namerec->name.name, 15);
strupper(buf);
/* Put the name type and netbios flags in the buffer. */
diff -ur rpcclient/display.c.010622 rpcclient/display.c
--- rpcclient/display.c.010622 Thu Jun 21 14:12:40 2001
+++ rpcclient/display.c Fri Jun 22 15:05:20 2001
@@ -716,8 +716,12 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-15.15s%-20s %s\n",
- sname, get_server_type_str(type), comment);
+ pstring s1, s2;
+
+ dos_to_unix(s1, strncpy_fill(s1, sname, 15));
+ dos_to_unix(s2, comment);
+ fprintf(out_hnd, "\t%s%-20s %s\n",
+ s1, get_server_type_str(type), s2);
break;
}
case ACTION_FOOTER:
@@ -741,8 +745,12 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-15.15s%-10.10s%s\n",
- sname, get_share_type_str(type), comment);
+ pstring s1, s2;
+
+ dos_to_unix(s1, strncpy_fill(s1, sname, 15));
+ dos_to_unix(s2, comment);
+ fprintf(out_hnd, "\t%s%-10.10s%s\n",
+ s1, get_share_type_str(type), s2);
break;
}
case ACTION_FOOTER:
@@ -769,8 +777,12 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-15.15s%-10.10s%s %x %x %x %s %s\n",
- sname, get_share_type_str(type), comment,
+ pstring s1, s2;
+
+ dos_to_unix(s1, strncpy_fill(s1, sname, 15));
+ dos_to_unix(s2, comment);
+ fprintf(out_hnd, "\t%s%-10.10s%s %x %x %x %s %s\n",
+ s1, get_share_type_str(type), s2,
perms, max_uses, num_uses, path, passwd);
break;
}
@@ -796,7 +808,10 @@
}
case ACTION_ENUMERATE:
{
- fprintf(out_hnd, "\t%-21.21s\n", sname);
+ pstring s;
+
+ dos_to_unix(s, strncpy_fill(s, sname, 21));
+ fprintf(out_hnd, "\t%s\n", s);
break;
}
case ACTION_FOOTER:
----- Cut Here -----
-----
TAKAHASHI Motonobu mailto:monyo at samba.gr.jp
Samba Users Group Japan http://www.samba.gr.jp/
More information about the samba-technical
mailing list