Avoid cutting in the middle of UTF-8 string.
* include/grub/charset.h (grub_getend): New function. * grub-core/script/function.c (grub_script_function_find): Use grub_getend. * grub-core/normal/completion.c (add_completion): Likewise.
This commit is contained in:
parent
f3cb4a4e57
commit
4d8c476536
4 changed files with 46 additions and 1 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Avoid cutting in the middle of UTF-8 string.
|
||||||
|
|
||||||
|
* include/grub/charset.h (grub_getend): New function.
|
||||||
|
* grub-core/script/function.c (grub_script_function_find): Use
|
||||||
|
grub_getend.
|
||||||
|
* grub-core/normal/completion.c (add_completion): Likewise.
|
||||||
|
|
||||||
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
|
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/normal/charset.c (grub_ucs4_to_utf8): Small stylistic fix.
|
* grub-core/normal/charset.c (grub_ucs4_to_utf8): Small stylistic fix.
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/parser.h>
|
#include <grub/parser.h>
|
||||||
#include <grub/extcmd.h>
|
#include <grub/extcmd.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
|
||||||
/* The current word. */
|
/* The current word. */
|
||||||
static const char *current_word;
|
static const char *current_word;
|
||||||
|
@ -86,6 +87,7 @@ add_completion (const char *completion, const char *extra,
|
||||||
s++;
|
s++;
|
||||||
t++;
|
t++;
|
||||||
}
|
}
|
||||||
|
s = match + grub_getend (match, s);
|
||||||
|
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <grub/script_sh.h>
|
#include <grub/script_sh.h>
|
||||||
#include <grub/parser.h>
|
#include <grub/parser.h>
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
|
||||||
grub_script_function_t grub_script_function_list;
|
grub_script_function_t grub_script_function_list;
|
||||||
|
|
||||||
|
@ -99,7 +100,14 @@ grub_script_function_find (char *functionname)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (! func)
|
if (! func)
|
||||||
grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%.20s'", functionname);
|
{
|
||||||
|
char tmp[21];
|
||||||
|
grub_strncpy (tmp, functionname, 20);
|
||||||
|
tmp[20] = 0;
|
||||||
|
/* Avoid truncating inside UTF-8 character. */
|
||||||
|
tmp[grub_getend (tmp, tmp + grub_strlen (tmp))] = 0;
|
||||||
|
grub_error (GRUB_ERR_UNKNOWN_COMMAND, "unknown command `%s'", tmp);
|
||||||
|
}
|
||||||
|
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,32 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
|
||||||
const grub_uint8_t *src, grub_size_t srcsize,
|
const grub_uint8_t *src, grub_size_t srcsize,
|
||||||
const grub_uint8_t **srcend);
|
const grub_uint8_t **srcend);
|
||||||
|
|
||||||
|
/* Determine the last position where the UTF-8 string [beg, end) can
|
||||||
|
be safely cut. */
|
||||||
|
static inline grub_size_t
|
||||||
|
grub_getend (const char *beg, const char *end)
|
||||||
|
{
|
||||||
|
const char *ptr;
|
||||||
|
for (ptr = end - 1; ptr >= beg; ptr--)
|
||||||
|
if ((*ptr & GRUB_UINT8_2_LEADINGBITS) != GRUB_UINT8_1_LEADINGBIT)
|
||||||
|
break;
|
||||||
|
if (ptr < beg)
|
||||||
|
return 0;
|
||||||
|
if ((*ptr & GRUB_UINT8_1_LEADINGBIT) == 0)
|
||||||
|
return ptr + 1 - beg;
|
||||||
|
if ((*ptr & GRUB_UINT8_3_LEADINGBITS) == GRUB_UINT8_2_LEADINGBITS
|
||||||
|
&& ptr + 2 <= end)
|
||||||
|
return ptr + 2 - beg;
|
||||||
|
if ((*ptr & GRUB_UINT8_4_LEADINGBITS) == GRUB_UINT8_3_LEADINGBITS
|
||||||
|
&& ptr + 3 <= end)
|
||||||
|
return ptr + 3 - beg;
|
||||||
|
if ((*ptr & GRUB_UINT8_5_LEADINGBITS) == GRUB_UINT8_4_LEADINGBITS
|
||||||
|
&& ptr + 4 <= end)
|
||||||
|
return ptr + 4 - beg;
|
||||||
|
/* Invalid character or incomplete. Cut before it. */
|
||||||
|
return ptr - beg;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert UTF-16 to UTF-8. */
|
/* Convert UTF-16 to UTF-8. */
|
||||||
static inline grub_uint8_t *
|
static inline grub_uint8_t *
|
||||||
grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src,
|
grub_utf16_to_utf8 (grub_uint8_t *dest, const grub_uint16_t *src,
|
||||||
|
|
Loading…
Reference in a new issue