Subject: bug#41122: closed (Re: bug#41122: 27.0.91; [Patch] 'Attempt to shape unibyte char' when using ligatures)

From: [email-masked] (GNU bug Tracking System)
Date: Thu, 07 May 2020 12:41:02 +0000

Your bug report

#41122: 27.0.91; [Patch] 'Attempt to shape unibyte char' when using ligatures

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
41122: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=41122
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#41122: 27.0.91; [Patch] 'Attempt to shape unibyte char' when using ligatures
From: Eli Zaretskii <[email-masked]>
To: Tom Regner <[email-masked]>
Cc: [email-masked]
Date: Thu, 07 May 2020 15:40:08 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> Date: Thu, 07 May 2020 10:17:26 +0200
> From: Tom Regner <[email-masked]>
> 
> sometimes an emacs frame 'freezes' when a buffer with ligatures is
> created with the message 'Attempt to shape unibyte char'.  Killing
> the buffer from another frame 'unfreezes' the affected frame.

This problem is already fixed on the master branch.  (It is too late
to apply such changes to the emacs-27 release branch.)

>    if (NILP (string))
>      {
> -      if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
> -	error ("Attempt to shape unibyte text");
> -      validate_region (&from, &to);
> +     validate_region (&from, &to);
>        frompos = XFIXNAT (from);
>        topos = XFIXNAT (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;

This part is incorrect: unibyte buffers should not be subject to
character composition, even if the bytes found there happen to be
ASCII bytes.

> +      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 = string_char_to_byte (string, frompos);
> +      }

This part (or its moral equivalent) is already on the master branch.

Thanks.

Subject: 27.0.91; [Patch] 'Attempt to shape unibyte char' when using ligatures
From: Tom Regner <[email-masked]>
To: [email-masked]
Date: Thu, 07 May 2020 10:17:26 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello,

sometimes an emacs frame 'freezes' when a buffer with ligatures is 
created
with the message 'Attempt to shape unibyte char'.  Killing the buffer 
from
another frame 'unfreezes' the affected frame.

I found a patch (created in 2016) here:
https://github.com/tonsky/FiraCode/files/107350/unibyte.diff.txt

I manually applied the changes to the current (as of this writing) state 
of
the emacs27 branch.  It compiles cleanly and solves the problem -- a
freshly compiled emacs27 branch (27.0.91) did freeze all code buffers I
tried to create without the changes; no freezes compiled with the 
attached
patch.

Please consider applying this patch, or to fix the problem in another 
way.

Thank you for your work on Emacs -- my daily life (work and private) 
would
be a lot worse without it.

kind regards,
Tom
-------------------------------- emacs info ----------------------

In GNU Emacs 27.0.91 (build 2, x86_64-pc-linux-gnu, GTK+ Version 
3.22.30)
  of 2020-05-07 built on cranston
Repository revision: 76516465bff31d35ea93bcb2badb14c642bb5767
Repository branch: emacs-27
Windowing system distributor 'The X.Org Foundation', version 
11.0.11906000
System Description: Ubuntu 18.04.4 LTS

Recent messages:
LSP :: jsts-ls:17101 initialized successfully
Menu-Bar mode disabled
Menu Bar mode disabled.  Use M-x menu-bar-mode to make the menu bar 
appear.
Making font-lock-function buffer-local while locally let-bound!
Making poly-lock-allow-fontification buffer-local while locally 
let-bound!
Select Projectile command [?DRTVabdefgjkorsv]: f
File mode specification error: (wrong-type-argument hash-table-p nil)
Quit
Vterm needs `vterm-module' to work.  Compile it now? (y or n) y
Compilation of ‘emacs-libvterm’ module succeeded

Configured using:
  'configure --with-json'

Configured features:
XPM JPEG TIFF GIF PNG RSVG SOUND DBUS GSETTINGS GLIB NOTIFY INOTIFY
GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF XFT ZLIB
TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS JSON PDUMPER LCMS2
GMP

Important settings:
   value of $LC_MONETARY: de_DE.UTF-8
   value of $LC_NUMERIC: de_DE.UTF-8
   value of $LC_TIME: de_DE.UTF-8
   value of $LANG: en_US.UTF-8
   locale-coding-system: utf-8-unix

Major mode: O

Minor modes in effect:
   poly-org-mode: t
   bug-reference-mode: t
   global-magit-file-mode: t
   magit-file-mode: t
   magit-wip-initial-backup-mode: t
   magit-wip-before-change-mode: t
   magit-wip-after-apply-mode: t
   magit-wip-after-save-mode: t
   magit-wip-after-save-local-mode: t
   magit-wip-mode: t
   magit-auto-revert-mode: t
   global-git-commit-mode: t
   async-bytecomp-package-mode: t
   dap-tooltip-mode: t
   which-key-posframe-mode: t
   volatile-highlights-mode: t
   all-the-icons-ibuffer-mode: t
   mini-frame-mode: t
   which-key-mode: t
   boon-mode: t
   boon-local-mode: t
   beacon-mode: t
   doom-modeline-mode: t
   cyphejor-mode: t
   global-diff-hl-mode: t
   diff-hl-mode: t
   company-box-mode: t
   global-company-mode: t
   company-mode: t
   popwin-mode: t
   global-undo-tree-mode: t
   undo-tree-mode: t
   all-the-icons-ivy-rich-mode: t
   ivy-rich-mode: t
   counsel-projectile-mode: t
   ivy-mode: t
   shell-dirtrack-mode: t
   show-paren-mode: t
   persp-mode-projectile-bridge-mode: t
   projectile-mode: t
   persp-mode: t
   engine-mode: t
   electric-pair-mode: t
   dap-ui-mode: t
   lsp-treemacs-sync-mode: t
   treemacs-filewatch-mode: t
   treemacs-follow-mode: t
   treemacs-git-mode: deferred
   treemacs-fringe-indicator-mode: t
   dap-mode: t
   global-auto-revert-mode: t
   yas-global-mode: t
   yas-minor-mode: t
   auto-compile-on-load-mode: t
   pallet-mode: t
   tooltip-mode: t
   global-eldoc-mode: t
   electric-indent-mode: t
   mouse-wheel-mode: t
   file-name-shadow-mode: t
   global-font-lock-mode: t
   font-lock-mode: t
   blink-cursor-mode: t
   auto-composition-mode: t
   auto-encryption-mode: t
   auto-compression-mode: t
   column-number-mode: t
   line-number-mode: t
   global-visual-line-mode: t
   visual-line-mode: t
   transient-mark-mode: t

Load-path shadows:
/usr/lib/node_modules/tern/emacs/tern hides 
/home/tregner/.emacs.d/.cask/27.0/elpa/tern-20181108.722/tern
/home/tregner/.emacs.d/.cask/27.0/elpa/circe-20200125.2110/tracking 
hides 
/home/tregner/.emacs.d/.cask/27.0/elpa/tracking-20171210.2102/tracking
/home/tregner/.emacs.d/.cask/27.0/elpa/circe-20200125.2110/shorten hides 
/home/tregner/.emacs.d/.cask/27.0/elpa/tracking-20171210.2102/shorten
~/.local/share/icons-in-terminal/icons-in-terminal hides 
/home/tregner/.emacs.d/site/icons-in-terminal
/home/tregner/.emacs.d/.cask/27.0/elpa/dap-mode-20200505.426/dap-php 
hides /home/tregner/.emacs.d/site/dap-php
/home/tregner/.emacs.src.d/org-mode/lisp/org-timer hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-timer
/home/tregner/.emacs.src.d/org-mode/lisp/org-attach hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-attach
/home/tregner/.emacs.src.d/org-mode/lisp/ob-groovy hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-groovy
/home/tregner/.emacs.src.d/org-mode/lisp/org-footnote hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-footnote
/home/tregner/.emacs.src.d/org-mode/lisp/ob-sed hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-sed
/home/tregner/.emacs.src.d/org-mode/lisp/ob-js hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-js
/home/tregner/.emacs.src.d/org-mode/lisp/org-capture hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-capture
/home/tregner/.emacs.src.d/org-mode/lisp/ob-lob hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-lob
/home/tregner/.emacs.src.d/org-mode/lisp/ox-icalendar hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-icalendar
/home/tregner/.emacs.src.d/org-mode/lisp/ob-J hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-J
/home/tregner/.emacs.src.d/org-mode/lisp/org-element hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-element
/home/tregner/.emacs.src.d/org-mode/lisp/ob-shell hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-shell
/home/tregner/.emacs.src.d/org-mode/lisp/org-list hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-list
/home/tregner/.emacs.src.d/org-mode/lisp/ob-makefile hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-makefile
/home/tregner/.emacs.src.d/org-mode/lisp/ob-core hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-core
/home/tregner/.emacs.src.d/org-mode/lisp/ob-C hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-C
/home/tregner/.emacs.src.d/org-mode/lisp/ob-plantuml hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-plantuml
/home/tregner/.emacs.src.d/org-mode/lisp/org-crypt hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-crypt
/home/tregner/.emacs.src.d/org-mode/lisp/org-src hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-src
/home/tregner/.emacs.src.d/org-mode/lisp/org-indent hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-indent
/home/tregner/.emacs.src.d/org-mode/lisp/org-macs hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-macs
/home/tregner/.emacs.src.d/org-mode/lisp/org-inlinetask hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-inlinetask
/home/tregner/.emacs.src.d/org-mode/lisp/ox-texinfo hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-texinfo
/home/tregner/.emacs.src.d/org-mode/lisp/org-colview hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-colview
/home/tregner/.emacs.src.d/org-mode/lisp/org-pcomplete hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-pcomplete
/home/tregner/.emacs.src.d/org-mode/lisp/ox-ascii hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-ascii
/home/tregner/.emacs.src.d/org-mode/lisp/org-macro hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-macro
/home/tregner/.emacs.src.d/org-mode/lisp/org-archive hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-archive
/home/tregner/.emacs.src.d/org-mode/lisp/ob-lua hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-lua
/home/tregner/.emacs.src.d/org-mode/lisp/ob-R hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-R
/home/tregner/.emacs.src.d/org-mode/lisp/org-feed hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-feed
/home/tregner/.emacs.src.d/org-mode/lisp/ob-scheme hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-scheme
/home/tregner/.emacs.src.d/org-mode/lisp/org-table hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-table
/home/tregner/.emacs.src.d/org-mode/lisp/ob-lilypond hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-lilypond
/home/tregner/.emacs.src.d/org-mode/lisp/org-datetree hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-datetree
/home/tregner/.emacs.src.d/org-mode/lisp/ob-lisp hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-lisp
/home/tregner/.emacs.src.d/org-mode/lisp/org-habit hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-habit
/home/tregner/.emacs.src.d/org-mode/lisp/ob-calc hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-calc
/home/tregner/.emacs.src.d/org-mode/lisp/ob-css hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-css
/home/tregner/.emacs.src.d/org-mode/lisp/org-mouse hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-mouse
/home/tregner/.emacs.src.d/org-mode/lisp/ob-octave hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-octave
/home/tregner/.emacs.src.d/org-mode/lisp/ox-beamer hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-beamer
/home/tregner/.emacs.src.d/org-mode/lisp/ox-org hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-org
/home/tregner/.emacs.src.d/org-mode/lisp/ox-man hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-man
/home/tregner/.emacs.src.d/org-mode/lisp/ox-publish hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-publish
/home/tregner/.emacs.src.d/org-mode/lisp/ob-asymptote hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-asymptote
/home/tregner/.emacs.src.d/org-mode/lisp/ob-eval hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-eval
/home/tregner/.emacs.src.d/org-mode/lisp/ob-org hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-org
/home/tregner/.emacs.src.d/org-mode/lisp/ob-ruby hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-ruby
/home/tregner/.emacs.src.d/org-mode/lisp/ob-ref hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-ref
/home/tregner/.emacs.src.d/org-mode/lisp/ob-java hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-java
/home/tregner/.emacs.src.d/org-mode/lisp/ob-coq hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-coq
/home/tregner/.emacs.src.d/org-mode/lisp/ob-comint hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-comint
/home/tregner/.emacs.src.d/org-mode/lisp/ob-picolisp hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-picolisp
/home/tregner/.emacs.src.d/org-mode/lisp/ob-perl hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-perl
/home/tregner/.emacs.src.d/org-mode/lisp/org-duration hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-duration
/home/tregner/.emacs.src.d/org-mode/lisp/ob-screen hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-screen
/home/tregner/.emacs.src.d/org-mode/lisp/ob-awk hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-awk
/home/tregner/.emacs.src.d/org-mode/lisp/org-mobile hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-mobile
/home/tregner/.emacs.src.d/org-mode/lisp/ob-ledger hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-ledger
/home/tregner/.emacs.src.d/org-mode/lisp/ox-md hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-md
/home/tregner/.emacs.src.d/org-mode/lisp/org-faces hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-faces
/home/tregner/.emacs.src.d/org-mode/lisp/ob-processing hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-processing
/home/tregner/.emacs.src.d/org-mode/lisp/org-id hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-id
/home/tregner/.emacs.src.d/org-mode/lisp/ob-table hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-table
/home/tregner/.emacs.src.d/org-mode/lisp/ob-exp hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-exp
/home/tregner/.emacs.src.d/org-mode/lisp/org-compat hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-compat
/home/tregner/.emacs.src.d/org-mode/lisp/ob-ditaa hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-ditaa
/home/tregner/.emacs.src.d/org-mode/lisp/ox hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox
/home/tregner/.emacs.src.d/org-mode/lisp/ob-io hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-io
/home/tregner/.emacs.src.d/org-mode/lisp/ob hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob
/home/tregner/.emacs.src.d/org-mode/lisp/ob-latex hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-latex
/home/tregner/.emacs.src.d/org-mode/lisp/ob-matlab hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-matlab
/home/tregner/.emacs.src.d/org-mode/lisp/ob-hledger hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-hledger
/home/tregner/.emacs.src.d/org-mode/lisp/ox-latex hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-latex
/home/tregner/.emacs.src.d/org-mode/lisp/org-clock hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-clock
/home/tregner/.emacs.src.d/org-mode/lisp/ob-mscgen hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-mscgen
/home/tregner/.emacs.src.d/org-mode/lisp/ob-sass hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-sass
/home/tregner/.emacs.src.d/org-mode/lisp/ob-shen hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-shen
/home/tregner/.emacs.src.d/org-mode/lisp/ob-forth hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-forth
/home/tregner/.emacs.src.d/org-mode/lisp/ob-stan hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-stan
/home/tregner/.emacs.src.d/org-mode/lisp/ob-ocaml hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-ocaml
/home/tregner/.emacs.src.d/org-mode/lisp/ob-ebnf hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-ebnf
/home/tregner/.emacs.src.d/org-mode/lisp/ob-haskell hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-haskell
/home/tregner/.emacs.src.d/org-mode/lisp/ob-fortran hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-fortran
/home/tregner/.emacs.src.d/org-mode/lisp/ob-sql hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-sql
/home/tregner/.emacs.src.d/org-mode/lisp/ob-sqlite hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-sqlite
/home/tregner/.emacs.src.d/org-mode/lisp/org hides 
/usr/local/share/emacs/27.0.91/lisp/org/org
/home/tregner/.emacs.src.d/org-mode/lisp/org-entities hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-entities
/home/tregner/.emacs.src.d/org-mode/lisp/org-lint hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-lint
/home/tregner/.emacs.src.d/org-mode/lisp/ox-odt hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-odt
/home/tregner/.emacs.src.d/org-mode/lisp/ob-maxima hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-maxima
/home/tregner/.emacs.src.d/org-mode/lisp/org-loaddefs hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-loaddefs
/home/tregner/.emacs.src.d/org-mode/lisp/ob-python hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-python
/home/tregner/.emacs.src.d/org-mode/lisp/ox-html hides 
/usr/local/share/emacs/27.0.91/lisp/org/ox-html
/home/tregner/.emacs.src.d/org-mode/lisp/org-agenda hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-agenda
/home/tregner/.emacs.src.d/org-mode/lisp/ob-vala hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-vala
/home/tregner/.emacs.src.d/org-mode/lisp/org-ctags hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-ctags
/home/tregner/.emacs.src.d/org-mode/lisp/ob-abc hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-abc
/home/tregner/.emacs.src.d/org-mode/lisp/org-plot hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-plot
/home/tregner/.emacs.src.d/org-mode/lisp/ob-dot hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-dot
/home/tregner/.emacs.src.d/org-mode/lisp/ob-clojure hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-clojure
/home/tregner/.emacs.src.d/org-mode/lisp/ob-tangle hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-tangle
/home/tregner/.emacs.src.d/org-mode/lisp/org-protocol hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-protocol
/home/tregner/.emacs.src.d/org-mode/lisp/ob-emacs-lisp hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-emacs-lisp
/home/tregner/.emacs.src.d/org-mode/lisp/org-version hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-version
/home/tregner/.emacs.src.d/org-mode/lisp/ob-gnuplot hides 
/usr/local/share/emacs/27.0.91/lisp/org/ob-gnuplot
/home/tregner/.emacs.src.d/org-mode/lisp/org-install hides 
/usr/local/share/emacs/27.0.91/lisp/org/org-install
/home/tregner/.emacs.d/.cask/27.0/elpa/map-2.1/map hides 
/usr/local/share/emacs/27.0.91/lisp/emacs-lisp/map

Features:
(shadow sort mail-extr emacsbug sendmail vterm vterm-module magit-extras
org-journal org-crypt cal-iso poly-org ggtags hippie-exp smex lsp-yaml
lsp-xml lsp-vhdl lsp-vetur lsp-html lsp-verilog lsp-terraform
lsp-solargraph lsp-rust lsp-pyls lsp-pwsh lsp-perl lsp-metals lsp-json
lsp-intelephense lsp-haxe lsp-go lsp-gdscript lsp-fsharp lsp-eslint
lsp-erlang lsp-elm lsp-css lsp-csharp lsp-clojure indent-guide
company-oddmuse company-keywords company-etags company-gtags
company-dabbrev-code company-dabbrev company-files company-cmake
company-xcode company-clang company-semantic company-eclim
company-template company-bbdb whitespace .emacs org-rmail org-mhe
org-irc org-info org-gnus nnir gnus-sum shr svg dom gnus-group gnus-undo
gnus-start gnus-cloud nnimap nnmail mail-source utf7 nnoo gnus-spec
gnus-int gnus-range gnus-win gnus nnheader org-docview doc-view
image-mode exif org-bibtex bibtex org-bbdb org-w3m loadhist diminish
org-passwords prodigy forge-list forge-commands forge-semi
forge-bitbucket buck forge-gogs gogs forge-gitea gtea forge-gitlab glab
forge-github forge-notify forge-revnote forge-pullreq forge-issue
forge-topic forge-post forge-repo forge forge-core forge-db closql
emacsql-sqlite magithub magithub-dash magithub-notification
magithub-orgs magithub-issue-tricks magithub-issue-post
magithub-edit-mode magithub-repo magithub-ci magithub-issue
magithub-label magithub-user magithub-core magithub-faces
magithub-settings bug-reference ghub+ apiwrap apropos ghub-graphql
treepy gsexp ghub magit-bookmark magit-submodule magit-obsolete
magit-popup magit-blame magit-stash magit-reflog magit-bisect magit-push
magit-pull magit-fetch magit-clone magit-remote magit-commit
magit-sequence magit-notes magit-worktree magit-tag magit-merge
magit-branch magit-reset magit-files magit-refs magit-status magit
magit-repos magit-apply magit-wip magit-log magit-diff smerge-mode
magit-core magit-autorevert magit-margin magit-transient magit-process
magit-mode git-commit transient magit-git magit-section benchmark
magit-utils which-func crm log-edit message rfc822 mml mml-sec epa
gnus-util rmail rmail-loaddefs mm-decode mm-bodies mm-encode mailabbrev
gmm-utils mailheader pcvs-util with-editor async-bytecomp async server
outline-magic sql-indent yaml-mode nodejs-repl php-doc-block dap-mouse
dap-php dap-utils php-mode mode-local etags fileloop add-log cc-langs
php-face php php-project flymake-proc flymake speedbar sb-image ezimage
dframe elixir-mode elixir-format pkg-info url-http url-auth mail-parse
rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr url-gw elixir-smie
smie company-capf lsp-ivy lsp-origami origami origami-parsers lsp-ui
lsp-ui-flycheck lsp-ui-doc goto-addr lsp-ui-imenu lsp-ui-peek
lsp-ui-sideline flycheck lsp-clients lsp linum-relative linum
display-line-numbers which-key-posframe posframe popup-imenu popup
aql-mode polymode poly-lock polymode-base polymode-weave polymode-export
polymode-compat polymode-methods polymode-core polymode-classes
eieio-custom eieio-base volatile-highlights dired-x repl-toggle
expand-region text-mode-expansions cc-mode-expansions
the-org-mode-expansions js-mode-expansions flyspell-correct-ivy
flyspell-correct all-the-icons-ibuffer mini-frame which-key boon-qwerty
boon boon-moves er-basic-expansions expand-region-core
expand-region-custom boon-search boon-keys boon-main boon-arguments
multiple-cursors mc-hide-unmatched-lines-mode mc-separate-operations
rectangular-region-mode mc-mark-pop mc-mark-more mc-cycle-cursors
mc-edit-lines multiple-cursors-core rect boon-regs boon-utils boon-core
circe-color-nicks circe lui-irc-colors irc make-tls-process tls gnutls
lcs lui-format lui tracking shorten flyspell ispell circe-compat
company-postgresql emacsql-psql emacsql emacsql-compiler yequake
org-popnote ob-mermaid ob-sql-mode sql view ob-plantuml ob-http
ob-http-mode ob-gnuplot ob-lisp ob-sass ob-ditaa ob-shell plantuml-mode
alert log4e notifications dbus ido-completing-read+ flx-ido
minibuf-eldef ido xml gntp beacon doom-modeline doom-modeline-segments
let-alist doom-modeline-env doom-modeline-core shrink-path cyphejor
rainbow-delimiters dashboard dashboard-widgets time recentf
page-break-lines diff-hl face-remap vc-hg vc-git vc-dir vc vc-dispatcher
diff-mode color-theme-approximate modus-vivendi-theme icons-in-terminal
font-lock+ org-projectile org-category-capture org-capture company-box
company-box-doc company-box-icons company em-smart esh-mode em-term term
disp-table ehelp eshell esh-cmd esh-ext esh-opt esh-proc esh-io esh-arg
esh-module esh-groups popwin undo-tree diff fullframe all-the-icons-ivy
all-the-icons-ivy-rich all-the-icons all-the-icons-faces data-material
data-weathericons data-octicons data-fileicons data-faicons
data-alltheicons memoize ivy-rich treemacs-bookmarks bookmark
text-property-search pp counsel-projectile counsel xdg swiper ivy flx
delsel ivy-overlay colir hook-helpers tramp tramp-loaddefs trampver
tramp-integration files-x tramp-compat shell parse-time iso8601 ls-lisp
paren persp-mode-projectile-bridge projectile skeleton ibuf-macs
find-dired dired dired-loaddefs grep ibuf-ext ibuffer ibuffer-loaddefs
persp-mode golden-ratio engine-mode elec-pair dap-ui lsp-treemacs
treemacs treemacs-header-line treemacs-compatibility treemacs-mode
treemacs-interface treemacs-extensions treemacs-persistence
treemacs-mouse-interface treemacs-tag-follow-mode hydra
treemacs-filewatch-mode treemacs-tags treemacs-follow-mode
treemacs-rendering treemacs-async treemacs-workspaces treemacs-dom
treemacs-visuals treemacs-fringe-indicator treemacs-scope pulse
treemacs-faces treemacs-icons treemacs-themes treemacs-core-utils
pfuture ace-window avy hl-line treemacs-macros treemacs-logging
treemacs-customization gdb-mi gud bui bui-list bui-info bui-entry
bui-core bui-history bui-button bui-utils cus-edit dap-mode dap-overlays
lsp-mode elixir-yasnippets es-mode request autorevert mail-utils url
url-proxy url-privacy url-expand url-methods url-history url-cookie
url-domsuf mailcap js cc-mode cc-fonts cc-guess cc-menus cc-cmds
cc-styles cc-align cc-engine cc-vars cc-defs yasnippet cl-extra
help-mode xref project url-util tree-widget wid-edit spinner cl
network-stream puny nsm rmc markdown-mode derived color thingatpt lv
inline imenu ht filenotify ewoc em-glob esh-util dash-functional compile
bindat cus-start cus-load netrc jka-compr auto-compile packed
gnu-elpa-keyring-update epg epg-config pallet tex-site slime-autoloads
w3m-load warnings cask cask-bootstrap ansi package-recipe-mode
package-build-badges package-build package-recipe pcase eieio-compat
lisp-mnt shut-up epl rx git commander f dash s finder-inf info package
browse-url url-handlers url-parse auth-source eieio eieio-core cl-macs
eieio-loaddefs password-cache json map url-vars seq byte-opt gv bytecomp
byte-compile cconv edmacro kmacro org-element cl-seq avl-tree generator
org advice org-macro org-footnote org-pcomplete pcomplete org-list
org-faces org-entities time-date subr-x noutline outline easy-mmode
org-version ob-emacs-lisp ob ob-tangle org-src ob-ref ob-lob ob-table
ob-keys ob-exp ob-comint comint ansi-color ring ob-core ob-eval
org-compat org-macs org-loaddefs format-spec find-func cal-menu easymenu
calendar cal-loaddefs cl-loaddefs cl-lib tooltip eldoc electric uniquify
ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch timer
select scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame minibuffer cl-generic cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese composite charscript charprop case-table epa-hook
jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote threads dbusbind inotify lcms2 dynamic-setting
system-font-setting font-render-setting move-toolbar gtk x-toolkit x
multi-tty make-network-process emacs)

Memory information:
((conses 16 1947873 2965598)
  (symbols 48 83693 2)
  (strings 32 323317 188369)
  (string-bytes 1 13015498)
  (vectors 16 84039)
  (vector-slots 8 1725288 536404)
  (floats 8 1274 1632)
  (intervals 56 9505 2526)
  (buffers 1000 35))

-- 
Tom Regner

diff --git a/src/character.h b/src/character.h
index 3642a54044..75672f8d54 100644
--- a/src/character.h
+++ b/src/character.h
@@ -122,6 +122,10 @@ #define MAKE_CHAR_MULTIBYTE(c) \
 /* 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) (FIXNATP (x) && XFIXNAT (x) <= MAX_CHAR)
 
diff --git a/src/composite.c b/src/composite.c
index 364d5c9316..121a554754 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -1744,20 +1744,45 @@ Otherwise (for terminal display), FONT-OBJECT must be a terminal ID, a
 
   if (NILP (string))
     {
-      if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
-	error ("Attempt to shape unibyte text");
-      validate_region (&from, &to);
+     validate_region (&from, &to);
       frompos = XFIXNAT (from);
       topos = XFIXNAT (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 = string_char_to_byte (string, frompos);
+      }
     }
 
   header = fill_gstring_header (frompos, frombyte,