Skip to content

Commit b7c6936

Browse files
[Android] Exception thrown when give more than 5000 characters to the Text property of Entry. (#30242)
### Issue Details: Exception thrown when give more than 5000 characters to the Text property of Entry on Android platform. ### Root Cause: When the Entry contains more than 5000 characters and the IsPassword property is mapped before the MaxLength property, the EditText input type is set to InputTypes.ClassText | InputTypes.TextVariationNormal. After the input type is updated, we attempts to restore the previous cursor position, which exceeds 5000 characters. This results in an IndexOutOfBoundsException during the selection process. ### Description of Change: To prevent the crash, I reordered the property mappers by applying the MaxLength mapper before the IsPassword mapper in EntryHandler **Tested the behavior in the following platforms.** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #30144 ### Screenshots | Before | After | |---------|--------| | The application is crashed | <Image src="https://github.com/user-attachments/assets/f690b53b-a2f2-4adb-89b4-e190b94179b9"> |
1 parent 17b7df9 commit b7c6936

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

src/Controls/tests/DeviceTests/Elements/Entry/EntryTests.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,65 @@ await InvokeOnMainThreadAsync(async () =>
238238
});
239239
}
240240

241+
[Fact(DisplayName = "Android crash when Entry has more than 5000 characters")]
242+
[Category(TestCategory.Entry)]
243+
public async Task EntryWithLongTextDoesNotCrash()
244+
{
245+
string longText = new string('A', 5001);
246+
var entry = new Entry
247+
{
248+
Text = longText,
249+
};
250+
251+
var handler = await CreateHandlerAsync<EntryHandler>(entry);
252+
var platformEntry = GetPlatformControl(handler);
253+
Assert.NotNull(platformEntry);
254+
Assert.Equal(longText, await GetPlatformText(handler));
255+
256+
}
257+
258+
[Fact(DisplayName = "Entry with longer text and short text updates correctly")]
259+
[Category(TestCategory.Entry)]
260+
public async Task EntryWithLongTextAndShortText_UpdatesTextCorrectly()
261+
{
262+
string longText = new string('A', 5001);
263+
var entry = new Entry
264+
{
265+
Text = longText
266+
};
267+
268+
var handler = await CreateHandlerAsync<EntryHandler>(entry);
269+
#if !ANDROID
270+
await InvokeOnMainThreadAsync(() =>
271+
{
272+
SetPlatformText(handler, "short");
273+
});
274+
#else
275+
SetPlatformText(handler, "short");
276+
#endif
277+
Assert.Equal("short", await GetPlatformText(handler));
278+
}
279+
280+
[Fact(
281+
#if WINDOWS
282+
Skip = "Fails on Windows"
283+
#endif
284+
)]
285+
[Description("Entry MaxLength and Text property order is respected")]
286+
[Category(TestCategory.Entry)]
287+
public async Task EntryMaxLengthAndTextOrder_RespectsMaxLength()
288+
{
289+
string longText = new string('C', 50);
290+
var entry = new Entry
291+
{
292+
MaxLength = 10,
293+
Text = longText
294+
};
295+
296+
var handler = await CreateHandlerAsync<EntryHandler>(entry);
297+
Assert.Equal(longText.Substring(0, 10), await GetPlatformText(handler));
298+
}
299+
241300
[Category(TestCategory.Entry)]
242301
[Collection(RunInNewWindowCollection)]
243302
public class EntryTextInputTests : TextInputTests<EntryHandler, Entry>

src/Core/src/Handlers/Entry/EntryHandler.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ namespace Microsoft.Maui.Handlers
1717
{
1818
public partial class EntryHandler : IEntryHandler
1919
{
20-
public static IPropertyMapper<IEntry, IEntryHandler> Mapper = new PropertyMapper<IEntry, IEntryHandler>(ViewHandler.ViewMapper)
20+
private static readonly IPropertyMapper<IEntry, IEntryHandler> EntryPriorityMapper = new PropertyMapper<IEntry, IEntryHandler>()
21+
{
22+
[nameof(IEntry.MaxLength)] = MapMaxLength,
23+
};
24+
25+
public static IPropertyMapper<IEntry, IEntryHandler> Mapper = new PropertyMapper<IEntry, IEntryHandler>(ViewHandler.ViewMapper, EntryPriorityMapper)
2126
{
2227
[nameof(IEntry.Background)] = MapBackground,
2328
[nameof(IEntry.CharacterSpacing)] = MapCharacterSpacing,
@@ -30,7 +35,6 @@ public partial class EntryHandler : IEntryHandler
3035
[nameof(IEntry.IsTextPredictionEnabled)] = MapIsTextPredictionEnabled,
3136
[nameof(IEntry.IsSpellCheckEnabled)] = MapIsSpellCheckEnabled,
3237
[nameof(IEntry.Keyboard)] = MapKeyboard,
33-
[nameof(IEntry.MaxLength)] = MapMaxLength,
3438
[nameof(IEntry.Placeholder)] = MapPlaceholder,
3539
[nameof(IEntry.PlaceholderColor)] = MapPlaceholderColor,
3640
[nameof(IEntry.ReturnType)] = MapReturnType,

0 commit comments

Comments
 (0)