From 812dd5119645a09bc025a9dddedad9474d12ecb6 Mon Sep 17 00:00:00 2001 From: Christopher McDevitt Date: Wed, 4 Nov 2015 22:19:03 +0000 Subject: [PATCH] mac ligature fix from railwaycat emacs Stops "Attempt to shape unibyte text" errors when using ligatures Taken from https://github.com/railwaycat/mirror-emacs-mac/commit/e7a046987d66136da55ae10a9ef90728d1442cbb#diff-9114056b032516fa2de10ffaaa8e8ea7R1769 --- src/character.h | 4 ++++ src/composite.c | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/character.h b/src/character.h index 871c1c3de959..8cc750f8176b 100644 --- a/src/character.h +++ b/src/character.h @@ -97,6 +97,7 @@ enum /* Return the raw 8-bit byte for character C. */ #define CHAR_TO_BYTE8(c) (CHAR_BYTE8_P (c) ? (c) - 0x3FFF00 : (c & 0xFF)) + /* Return the raw 8-bit byte for character C, or -1 if C doesn't correspond to a byte. */ #define CHAR_TO_BYTE_SAFE(c) \ @@ -121,6 +122,9 @@ enum /* This is the maximum byte length of multibyte form. */ #define MAX_MULTIBYTE_LENGTH 5 +/* Nonzero iff C is an ASCII byte. */ +#define ASCII_BYTE_P(c) UNSIGNED_CMP (c, <, 0x80) + /* Nonzero iff X is a character. */ #define CHARACTERP(x) (NATNUMP (x) && XFASTINT (x) <= MAX_CHAR) diff --git a/src/composite.c b/src/composite.c index 0f729bc5460c..80e15f10646e 100644 --- a/src/composite.c +++ b/src/composite.c @@ -1727,20 +1727,45 @@ should be ignored. */) if (NILP (string)) { - if (NILP (BVAR (current_buffer, enable_multibyte_characters))) - error ("Attempt to shape unibyte text"); + validate_region (&from, &to); frompos = XFASTINT (from); topos = XFASTINT (to); - frombyte = CHAR_TO_BYTE (frompos); + if (!NILP (BVAR (current_buffer, enable_multibyte_characters))) + frombyte = CHAR_TO_BYTE (frompos); + else + { + ptrdiff_t pos; + + /* fill_gstring_header below uses + FETCH_CHAR_ADVANCE_NO_CHECK that assumes the current + buffer is multibyte, but it is safe as long as it only + fetches ASCII chars. */ + for (pos = frompos; pos < topos; pos++) + if (!ASCII_BYTE_P (*(BYTE_POS_ADDR (pos)))) + error ("Attempt to shape non-ASCII part of unibyte text"); + frombyte = frompos; + } } else { CHECK_STRING (string); validate_subarray (string, from, to, SCHARS (string), &frompos, &topos); - if (! STRING_MULTIBYTE (string)) - error ("Attempt to shape unibyte text"); - frombyte = string_char_to_byte (string, frompos); + if (STRING_MULTIBYTE (string)) + frombyte = string_char_to_byte (string, frompos); + else + { + ptrdiff_t pos; + + /* fill_gstring_header below uses + FETCH_STRING_CHAR_ADVANCE_NO_CHECK that assumes the + string is multibyte, but it is safe as long as it only + fetches ASCII chars. */ + for (pos = frompos; pos < topos; pos++) + if (!ASCII_BYTE_P (SREF (string, pos))) + error ("Attempt to shape non-ASCII part of unibyte text"); + frombyte = frompos; + } } header = fill_gstring_header (Qnil, frompos, frombyte,