grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v5 06/16] include/grub/charset.h: Enhance grub_utf16_to_utf8()


From: Vitaly Kuzmichev
Subject: [PATCH v5 06/16] include/grub/charset.h: Enhance grub_utf16_to_utf8()
Date: Tue, 22 Aug 2023 23:39:14 +0200

This patch improves grub_utf16_to_utf8() helper function with
additional parameter which allows to explicitly specify UTF-16 string
characters byte order (CPU native, Big Endian or Little Endian).

Previously grub_utf16_to_utf8() function supported only CPU byte order,
which requires to create temporary buffer and perform convertion from
BE or LE to CPU byte order first.

Now this conversion is performed in grub_utf16_to_utf8() when it reads
characters from the string, so temporary buffer is not needed any more.

This patch also adds new UTF16_CPU type parameter to all calls
of grub_utf16_to_utf8(). This parameter makes no functional changes.

Also change characters reading in grub_utf16_to_utf8() to use
grub_get_unaligned16(), as some buffer pointers could be unaligned.

Signed-off-by: Vitaly Kuzmichev <vitaly.kuzmichev@rtsoft.de>
---
 grub-core/commands/efi/lsefisystab.c |  2 +-
 grub-core/commands/usbtest.c         |  2 +-
 grub-core/fs/f2fs.c                  |  2 +-
 grub-core/fs/fat.c                   |  8 +++++---
 grub-core/fs/hfsplus.c               |  4 ++--
 grub-core/fs/iso9660.c               |  2 +-
 grub-core/fs/jfs.c                   |  3 ++-
 grub-core/fs/ntfs.c                  |  2 +-
 grub-core/fs/udf.c                   |  3 ++-
 grub-core/kern/efi/efi.c             | 15 ++++++++++-----
 grub-core/loader/efi/chainloader.c   |  2 +-
 grub-core/loader/i386/xnu.c          |  2 +-
 grub-core/osdep/windows/hostdisk.c   |  2 +-
 include/grub/charset.h               | 16 ++++++++++++++--
 14 files changed, 43 insertions(+), 22 deletions(-)

diff --git a/grub-core/commands/efi/lsefisystab.c 
b/grub-core/commands/efi/lsefisystab.c
index 79ccee12a..31ecb7dc2 100644
--- a/grub-core/commands/efi/lsefisystab.c
+++ b/grub-core/commands/efi/lsefisystab.c
@@ -81,7 +81,7 @@ grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ 
((unused)),
     if (!vendor)
       return grub_errno;
     *grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor,
-                        vendor_utf16 - st->firmware_vendor) = 0;
+                        vendor_utf16 - st->firmware_vendor, UTF16_CPU) = 0;
     grub_printf ("%s", vendor);
     grub_free (vendor);
   }
diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
index 2c6d93fe6..0baa985b0 100644
--- a/grub-core/commands/usbtest.c
+++ b/grub-core/commands/usbtest.c
@@ -107,7 +107,7 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t 
index, int langid,
     }
 
   *grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str,
-                      descstrp->length / 2 - 1) = 0;
+                      descstrp->length / 2 - 1, UTF16_CPU) = 0;
   grub_free (descstrp);
 
   return GRUB_USB_ERR_NONE;
diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
index 855e24618..429a3db83 100644
--- a/grub-core/fs/f2fs.c
+++ b/grub-core/fs/f2fs.c
@@ -1267,7 +1267,7 @@ grub_f2fs_utf16_to_utf8 (grub_uint16_t *in_buf_le)
     len++;
   }
 
-  *grub_utf16_to_utf8 (out_buf, in_buf, len) = '\0';
+  *grub_utf16_to_utf8 (out_buf, in_buf, len, UTF16_CPU) = '\0';
 
   return out_buf;
 }
diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
index c5efed724..24d0b629b 100644
--- a/grub-core/fs/fat.c
+++ b/grub-core/fs/fat.c
@@ -712,7 +712,7 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
            }
 
          *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename, ctxt->unibuf,
-                              slots * 15) = '\0';
+                              slots * 15, UTF16_CPU) = '\0';
 
          return 0;
        }
@@ -833,7 +833,8 @@ grub_fat_iterate_dir_next (grub_fshelp_node_t node,
 
              *grub_utf16_to_utf8 ((grub_uint8_t *) ctxt->filename,
                                   ctxt->unibuf,
-                                  slots * 13) = '\0';
+                                  slots * 13,
+                                  UTF16_CPU) = '\0';
 
              return GRUB_ERR_NONE;
            }
@@ -1171,7 +1172,8 @@ grub_fat_label (grub_device_t device, char **label)
            chc = ARRAY_SIZE (dir.type_specific.volume_label.str);
          for (i = 0; i < chc; i++)
            t[i] = grub_le_to_cpu16 (dir.type_specific.volume_label.str[i]);
-         *grub_utf16_to_utf8 ((grub_uint8_t *) *label, t, chc) = '\0';
+         *grub_utf16_to_utf8 ((grub_uint8_t *) *label, t,
+                              chc, UTF16_CPU) = '\0';
        }
     }
 
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index 295822f69..bee8eb7b6 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -795,7 +795,7 @@ list_nodes (void *record, void *hook_arg)
     }
 
   *grub_utf16_to_utf8 ((grub_uint8_t *) filename, keyname,
-                      grub_be_to_cpu16 (catkey->namelen)) = '\0';
+                      grub_be_to_cpu16 (catkey->namelen), UTF16_CPU) = '\0';
 
   grub_free (keyname);
 
@@ -1098,7 +1098,7 @@ grub_hfsplus_label (grub_device_t device, char **label)
     }
 
   *grub_utf16_to_utf8 ((grub_uint8_t *) (*label), label_name,
-                      label_len) = '\0';
+                      label_len, UTF16_CPU) = '\0';
 
   grub_free (label_name);
   grub_free (node);
diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c
index 8c348b59a..5eb6c1a0a 100644
--- a/grub-core/fs/iso9660.c
+++ b/grub-core/fs/iso9660.c
@@ -387,7 +387,7 @@ grub_iso9660_convert_string (grub_uint8_t *us, int len)
   for (i=0; i<len; i++)
     t[i] = grub_be_to_cpu16 (grub_get_unaligned16 (us + 2 * i));
 
-  *grub_utf16_to_utf8 ((grub_uint8_t *) p, t, len) = '\0';
+  *grub_utf16_to_utf8 ((grub_uint8_t *) p, t, len, UTF16_CPU) = '\0';
 
   return p;
 }
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
index 6f7c43904..0f19c9718 100644
--- a/grub-core/fs/jfs.c
+++ b/grub-core/fs/jfs.c
@@ -592,7 +592,8 @@ grub_jfs_getent (struct grub_jfs_diropen *diro)
   diro->index++;
 
   /* Convert the temporary UTF16 filename to UTF8.  */
-  *grub_utf16_to_utf8 ((grub_uint8_t *) (diro->name), filename, strpos) = '\0';
+  *grub_utf16_to_utf8 ((grub_uint8_t *) (diro->name), filename,
+                      strpos, UTF16_CPU) = '\0';
 
   return 0;
 }
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index bbdbe24ad..1bee35e87 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -566,7 +566,7 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
     }
   for (i = 0; i < len; i++)
     tmp[i] = grub_le_to_cpu16 (grub_get_unaligned16 (in + 2 * i));
-  *grub_utf16_to_utf8 (buf, tmp, len) = '\0';
+  *grub_utf16_to_utf8 (buf, tmp, len, UTF16_CPU) = '\0';
   grub_free (tmp);
   return (char *) buf;
 }
diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c
index b836e6107..6ad15632a 100644
--- a/grub-core/fs/udf.c
+++ b/grub-core/fs/udf.c
@@ -967,7 +967,8 @@ read_string (const grub_uint8_t *raw, grub_size_t sz, char 
*outbuf)
       outbuf = grub_malloc (size);
     }
   if (outbuf)
-    *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16, utf16len) = '\0';
+    *grub_utf16_to_utf8 ((grub_uint8_t *) outbuf, utf16,
+                        utf16len, UTF16_CPU) = '\0';
 
  fail:
   grub_free (utf16);
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index a2afd8de9..824784d9a 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -460,8 +460,10 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
              return NULL;
            }
          p = (char *) grub_utf16_to_utf8 ((unsigned char *) p,
-                                           grub_memcpy (dup_name, 
fp->path_name, len * sizeof (*dup_name)),
-                                           len);
+                                          grub_memcpy (dup_name,
+                                                       fp->path_name,
+                                                       len * sizeof 
(*dup_name)),
+                                          len, UTF16_CPU);
          grub_free (dup_name);
        }
 
@@ -914,9 +916,12 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
                        grub_free (buf);
                        break;
                      }
-                   *grub_utf16_to_utf8 (buf, grub_memcpy (dup_name, 
fp->path_name, len - 4),
-                                      (len - 4) / sizeof (grub_efi_char16_t))
-                     = '\0';
+                   *grub_utf16_to_utf8 (buf,
+                                        grub_memcpy (dup_name,
+                                                     fp->path_name,
+                                                     len - 4),
+                                        (len - 4) / sizeof (grub_efi_char16_t),
+                                        UTF16_CPU) = '\0';
                    grub_free (dup_name);
                  }
                else
diff --git a/grub-core/loader/efi/chainloader.c 
b/grub-core/loader/efi/chainloader.c
index 1de98f783..218a60e74 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -84,7 +84,7 @@ grub_chainloader_boot (void *context)
          if (buf)
            {
              *grub_utf16_to_utf8 ((grub_uint8_t *) buf,
-                                  exit_data, exit_data_size) = 0;
+                                  exit_data, exit_data_size, UTF16_CPU) = 0;
 
              grub_error (GRUB_ERR_BAD_OS, "%s", buf);
              grub_free (buf);
diff --git a/grub-core/loader/i386/xnu.c b/grub-core/loader/i386/xnu.c
index 4e31ce99a..f8a93acfb 100644
--- a/grub-core/loader/i386/xnu.c
+++ b/grub-core/loader/i386/xnu.c
@@ -342,7 +342,7 @@ grub_xnu_devprop_add_property_utf16 (struct 
grub_xnu_devprop_device_descriptor *
       return grub_errno;
     }
 
-  *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0';
+  *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen, UTF16_CPU) = '\0';
 
   err = grub_xnu_devprop_add_property (dev, utf8, utf16,
                                       namelen, data, datalen);
diff --git a/grub-core/osdep/windows/hostdisk.c 
b/grub-core/osdep/windows/hostdisk.c
index aaa6e2f8e..0e68de083 100644
--- a/grub-core/osdep/windows/hostdisk.c
+++ b/grub-core/osdep/windows/hostdisk.c
@@ -89,7 +89,7 @@ grub_util_tchar_to_utf8 (LPCTSTR in)
 
   size_t tsz = GRUB_MAX_UTF8_PER_UTF16 * ssz + 1;
   grub_uint8_t *ret = xmalloc (tsz);
-  *grub_utf16_to_utf8 (ret, in, ssz) = '\0';
+  *grub_utf16_to_utf8 (ret, in, ssz, UTF16_CPU) = '\0';
   return (char *) ret;
 }
 
diff --git a/include/grub/charset.h b/include/grub/charset.h
index 31a3b52dd..635d6df9e 100644
--- a/include/grub/charset.h
+++ b/include/grub/charset.h
@@ -49,6 +49,13 @@
 #define GRUB_UTF16_LOWER_SURROGATE(code) \
   (0xDC00 | (((code) - GRUB_UCS2_LIMIT) & 0x3ff))
 
+typedef enum grub_utf16_type
+  {
+    UTF16_CPU          = 0,
+    UTF16_LE           = 1,
+    UTF16_BE           = 2,
+  } grub_utf16_type_t;
+
 /* Process one character from UTF8 sequence.
    At beginning set *code = 0, *count = 0. Returns 0 on failure and
    1 on success. *count holds the number of trailing bytes.  */
@@ -198,13 +205,18 @@ grub_getend (const char *beg, const char *end)
 /* Convert UTF-16 to UTF-8.  */
 static inline grub_uint8_t *
 grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src,
-                   grub_size_t size)
+                   grub_size_t size, grub_utf16_type_t type)
 {
   grub_uint32_t code_high = 0;
 
   while (size--)
     {
-      grub_uint32_t code = *src++;
+      grub_uint32_t code = grub_get_unaligned16 (src);
+      src++;
+      if (type == UTF16_LE)
+       code = grub_le_to_cpu16 (code);
+      else if (type == UTF16_BE)
+       code = grub_be_to_cpu16 (code);
 
       if (code_high)
        {
-- 
2.34.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]