Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Typing `fl` or `fi` in a textbox crashes with Avalonia 11.0.10 on MacOS

Open nil4 opened this issue 5 months ago • 4 comments

Describe the bug

Apps built with Avalonia 11.0.10 and 11.1.0-beta1 packages crash repeatably on MacOS 14.4, when typing fi or fl in a text box.

To Reproduce

git clone https://github.com/Actipro/Avalonia-Controls.git
cd Avalonia-Controls/Samples/SampleBrowser/SampleBrowser.Desktop
dotnet run

Select Themes from the drop-down at the top-left corner, then type fl or fi in a textbox (e.g. E-mail Address below):

image

The text input is processed and shown as expected. Close the sample browser app.

Edit the file Avalonia-Controls/Samples/SampleBrowser/References/Avalonia.References.props and update:

	<PropertyGroup>
-		<AvaloniaVersion>11.0.7</AvaloniaVersion>
+		<AvaloniaVersion>11.0.10</AvaloniaVersion>
	</PropertyGroup>

Run the application again, this time using Avalonia 11.0.10 packages:

cd Avalonia-Controls/Samples/SampleBrowser/SampleBrowser.Desktop
dotnet run

Type fl or fi in one of the text boxes. The application crashes, printing this stack trace:

% dotnet run
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Avalonia.Media.GlyphRun.CreateGlyphRunMetrics()
   at Avalonia.Media.GlyphRun.get_BaselineOrigin()
   at Avalonia.Media.GlyphRun.CreateGlyphRunImpl()
   at Avalonia.Media.TextFormatting.TextLineImpl.CreateLineMetrics()
   at Avalonia.Media.TextFormatting.TextLineImpl.FinalizeLine()
   at Avalonia.Media.TextFormatting.TextFormatterImpl.FormatLine(ITextSource textSource, Int32 firstTextSourceIndex, Double paragraphWidth, TextParagraphProperties paragraphProperties, TextLineBreak previousLineBreak)
   at Avalonia.Media.TextFormatting.TextLayout.CreateTextLines()
   at Avalonia.Media.TextFormatting.TextLayout..ctor(String text, Typeface typeface, Double fontSize, IBrush foreground, TextAlignment textAlignment, TextWrapping textWrapping, TextTrimming textTrimming, TextDecorationCollection textDecorations, FlowDirection flowDirection, Double maxWidth, Double maxHeight, Double lineHeight, Double letterSpacing, Int32 maxLines, IReadOnlyList`1 textStyleOverrides)
   at Avalonia.Controls.Presenters.TextPresenter.CreateTextLayoutInternal(Size constraint, String text, Typeface typeface, IReadOnlyList`1 textStyleOverrides)
   at Avalonia.Controls.Presenters.TextPresenter.CreateTextLayout()
   at Avalonia.Controls.Presenters.TextPresenter.get_TextLayout()
   at Avalonia.Controls.Presenters.TextPresenter.MoveCaretToTextPosition(Int32 textPosition, Boolean trailingEdge)
   at Avalonia.Controls.TextBox.OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
   at Avalonia.Animation.Animatable.OnPropertyChangedCore(AvaloniaPropertyChangedEventArgs change)
   at Avalonia.PropertyStore.EffectiveValue`1.SetAndRaiseCore(ValueStore owner, StyledProperty`1 property, T value, BindingPriority priority, Boolean isOverriddenCurrentValue, Boolean isCoercedDefaultValue)
   at Avalonia.PropertyStore.EffectiveValue`1.SetCurrentValueAndRaise(ValueStore owner, StyledProperty`1 property, T value)
   at Avalonia.PropertyStore.ValueStore.SetCurrentValue[T](StyledProperty`1 property, T value)
   at Avalonia.AvaloniaObject.SetCurrentValue[T](StyledProperty`1 property, T value)
   at Avalonia.Controls.TextBox.OnCaretIndexChanged(AvaloniaPropertyChangedEventArgs e)
   at Avalonia.Controls.TextBox.OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
   at Avalonia.Animation.Animatable.OnPropertyChangedCore(AvaloniaPropertyChangedEventArgs change)
   at Avalonia.PropertyStore.EffectiveValue`1.SetAndRaiseCore(ValueStore owner, StyledProperty`1 property, T value, BindingPriority priority, Boolean isOverriddenCurrentValue, Boolean isCoercedDefaultValue)
   at Avalonia.PropertyStore.EffectiveValue`1.SetCurrentValueAndRaise(ValueStore owner, StyledProperty`1 property, T value)
   at Avalonia.PropertyStore.ValueStore.SetCurrentValue[T](StyledProperty`1 property, T value)
   at Avalonia.AvaloniaObject.SetCurrentValue[T](StyledProperty`1 property, T value)
   at Avalonia.Controls.TextBox.HandleTextInput(String input)
   at Avalonia.Controls.TextBox.OnTextInput(TextInputEventArgs e)
   at Avalonia.Input.InputElement.<>c.<.cctor>b__32_4(InputElement x, TextInputEventArgs e)
   at Avalonia.Reactive.LightweightObservableBase`1.PublishNext(T value)
   at Avalonia.Interactivity.EventRoute.RaiseEventImpl(RoutedEventArgs e)
   at Avalonia.Interactivity.Interactive.RaiseEvent(RoutedEventArgs e)
   at Avalonia.Input.KeyboardDevice.ProcessRawEvent(RawInputEventArgs e)
   at Avalonia.Controls.TopLevel.HandleInput(RawInputEventArgs e)
   at Avalonia.Native.WindowBaseImpl.RawTextInputEvent(UInt64 timeStamp, String text)
   at Avalonia.Native.WindowBaseImpl.WindowBaseEvents.Avalonia.Native.Interop.IAvnWindowBaseEvents.RawTextInputEvent(UInt64 timeStamp, String text)
   at Avalonia.Native.Interop.Impl.__MicroComIAvnWindowBaseEventsVTable.RawTextInputEvent(Void* this, UInt64 timeStamp, Byte* text)
--- End of stack trace from previous location ---
   at Avalonia.Native.DispatcherImpl.RunLoop(CancellationToken token)
   at Avalonia.Threading.DispatcherFrame.Run(IControlledDispatcherImpl impl)
   at Avalonia.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken)
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args)
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, Action`1 lifetimeBuilder)
   at ActiproSoftware.SampleBrowser.Program.Main(String[] args) in ~/dev/Avalonia-Controls/Samples/SampleBrowser/SampleBrowser.Desktop/Program.cs:line 22

The same crash also reproduces with Avalonia 11.1.0-beta1 packages.

Reverting <AvaloniaVersion> to 11.0.7, or 11.0.9, no longer reproes -- this appears to be a regression in 11.0.10 and later versions.

Expected behavior

Entering text that may result in ligatures being displayed (e.g. fi or fl) does not crash on MacOS.

Avalonia version

11.0.10, 11.1.0-beta1

OS

macOS

Additional context

No response

nil4 avatar Mar 12 '24 20:03 nil4

The same crash also happens on Linux, just typing fl into any textbox will cause it. Doesn't crash on Windows, though.

SourMesen avatar May 11 '24 05:05 SourMesen

received similar report in https://github.com/irihitech/Semi.Avalonia/issues/347

rabbitism avatar May 11 '24 05:05 rabbitism

I have tested the issue and found that inputting ff, fi, fl, ffi, or ffl does not cause an error. However, I observed that when deleting these characters, they are deleted together as a single unit.  I suspect this behavior is related to font ligatures. When I changed the font to Courier, the characters are deleted individually as expected.

https://github.com/AvaloniaUI/Avalonia/assets/54255897/61d28fb3-292d-4fc0-9881-66a979718c99

zdpcdt avatar May 18 '24 09:05 zdpcdt

Currently we handle hit testing via glyph clusters. So a delete action always removes the whole ligature.

Gillibald avatar May 18 '24 18:05 Gillibald