[bug] the last char of multibyte string may not be correctly shown

Samba-JP TAKAHASHI Motonobu monyo at samba.gr.jp
Tue Jun 26 16:53:51 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.

The patch attached previously is invalid. Please use the following
patch instead:

---- 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 -urNP ../../samba-head/source/client/client.c ./client/client.c
--- ../../samba-head/source/client/client.c	Thu May 10 06:50:07 2001
+++ ./client/client.c	Fri Jun 22 15:31:21 2001
@@ -1631,6 +1631,7 @@
                       const char *comment, void *state)
 {
         fstring typestr;
+	pstring s;
 
         *typestr=0;
 
@@ -1646,8 +1647,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);
 }
 
 
@@ -1673,7 +1674,10 @@
 static void server_fn(const char *name, uint32 m, 
                       const char *comment, void *state)
 {
-        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 -urNP ../../samba-head/source/include/proto.h ./include/proto.h
--- ../../samba-head/source/include/proto.h	Thu Jun 21 06:51:31 2001
+++ ./include/proto.h	Fri Jun 22 15:31:43 2001
@@ -1188,6 +1188,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 -urNP ../../samba-head/source/lib/util_str.c ./lib/util_str.c
--- ../../samba-head/source/lib/util_str.c	Mon May 14 06:50:06 2001
+++ ./lib/util_str.c	Fri Jun 22 15:33:46 2001
@@ -972,6 +972,41 @@
 }
 
 /****************************************************************************
+ 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);
+}
+
+/****************************************************************************
 like strncpy but copies up to the character marker.  always null terminates.
 returns a pointer to the character marker in the source string (src).
 ****************************************************************************/
diff -urNP ../../samba-head/source/libsmb/nmblib.c ./libsmb/nmblib.c
--- ../../samba-head/source/libsmb/nmblib.c	Mon Apr 16 06:50:15 2001
+++ ./libsmb/nmblib.c	Fri Jun 22 15:35:49 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 -urNP ../../samba-head/source/nmbd/nmbd_incomingrequests.c ./nmbd/nmbd_incomingrequests.c
--- ../../samba-head/source/nmbd/nmbd_incomingrequests.c	Tue Apr 25 09:45:42 2000
+++ ./nmbd/nmbd_incomingrequests.c	Fri Jun 22 15:36:23 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 -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	Fri Jun 22 15:38:31 2001
@@ -717,8 +717,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:
@@ -742,8 +746,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:
@@ -770,8 +778,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;
 		}
@@ -797,7 +809,10 @@
 		}
 		case ACTION_ENUMERATE:
 		{
-			fprintf(out_hnd, "\t%-21.21s\n", sname);
+			pstring s;
+
+			dos_to_unix(s, strncpy_fill(s, sname, 15));
+			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