Prevent crash

This commit is contained in:
M66B 2021-09-09 12:52:10 +02:00
parent 03e841b493
commit 974de60dd0
17 changed files with 98 additions and 27 deletions

View File

@ -275,7 +275,7 @@ public class ActivityEML extends ActivityBase {
}
int textColorLink = Helper.resolveColor(context, android.R.attr.textColorLink);
SpannableStringBuilder ssb = new SpannableStringBuilder();
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
getStructure(imessage, ssb, 0, textColorLink);
result.structure = ssb;

View File

@ -356,7 +356,7 @@ public class ActivitySignature extends ActivityBase {
if (etText.isRaw())
etText.getText().insert(start, "<img src=\"" + Html.escapeHtml(uri.toString()) + "\" />");
else {
SpannableStringBuilder ssb = new SpannableStringBuilder(etText.getText());
SpannableStringBuilder ssb = new SpannableStringBuilderEx(etText.getText());
ssb.insert(start, " \uFFFC"); // Object replacement character
String source = uri.toString();
Drawable d = ImageHelper.decodeImage(this, -1, source, true, 0, 1.0f, etText);

View File

@ -80,7 +80,7 @@ public class AdapterLog extends RecyclerView.Adapter<AdapterLog.ViewHolder> {
private void bindTo(EntityLog log) {
tvTime.setText(TF.format(log.time));
SpannableStringBuilder ssb = new SpannableStringBuilder(log.data);
SpannableStringBuilder ssb = new SpannableStringBuilderEx(log.data);
switch (log.type) {
case General:
break;

View File

@ -1996,7 +1996,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
}
private Spanned formatAddresses(Address[] addresses, boolean full, int max) {
SpannableStringBuilder ssb = new SpannableStringBuilder();
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
if (addresses == null || addresses.length == 0)
return ssb;
@ -4771,7 +4771,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
boolean confirm_links = prefs.getBoolean("confirm_links", true);
Uri guri = UriHelper.guessScheme(uri);
String scheme = guri.getScheme();
String host = guri.getHost();;
String host = guri.getHost();
;
boolean confirm_link =
!"https".equals(scheme) || TextUtils.isEmpty(host) ||
prefs.getBoolean(host + ".confirm_link", true);
@ -5451,7 +5452,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
}
private SpannableStringBuilder getKeywords(TupleMessageEx message) {
SpannableStringBuilder ssb = new SpannableStringBuilder();
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
if (message.keyword_titles == null || message.keyword_colors == null) {
ssb.append("Keywords missing!");
@ -6833,7 +6834,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
icon.setBounds(0, 0, iconSize, iconSize);
ImageSpan imageSpan = new CenteredImageSpan(icon);
SpannableStringBuilder ssb = new SpannableStringBuilder(language.name);
SpannableStringBuilder ssb = new SpannableStringBuilderEx(language.name);
ssb.insert(0, "\uFFFC\u2002"); // object replacement character, en space
ssb.setSpan(imageSpan, 0, 1, 0);
@ -6957,7 +6958,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
@Override
protected void onExecuted(Bundle args, DeepL.Translation translation) {
SpannableStringBuilder ssb = new SpannableStringBuilder(tvText.getText());
SpannableStringBuilder ssb = new SpannableStringBuilderEx(tvText.getText());
int start = ssb.getSpanStart(mark);
int end = ssb.getSpanEnd(mark);
int textColorPrimary = Helper.resolveColor(context, android.R.attr.textColorPrimary);

View File

@ -161,7 +161,7 @@ public class EditTextCompose extends FixedEditText {
try {
SpannableStringBuilder ssb;
if (raw)
ssb = new SpannableStringBuilder(html);
ssb = new SpannableStringBuilderEx(html);
else {
Document document = HtmlHelper.sanitizeCompose(context, html, false);
Spanned paste = HtmlHelper.fromDocument(context, document, new Html.ImageGetter() {
@ -172,7 +172,7 @@ public class EditTextCompose extends FixedEditText {
}
}, null);
ssb = new SpannableStringBuilder(paste);
ssb = new SpannableStringBuilderEx(paste);
QuoteSpan[] spans = ssb.getSpans(0, ssb.length(), QuoteSpan.class);
for (QuoteSpan span : spans) {
QuoteSpan q;

View File

@ -444,7 +444,7 @@ public class FragmentAnswer extends FragmentBase {
getContext().getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
int start = etText.getSelectionStart();
SpannableStringBuilder ssb = new SpannableStringBuilder(etText.getText());
SpannableStringBuilder ssb = new SpannableStringBuilderEx(etText.getText());
ssb.insert(start, " \uFFFC"); // Object replacement character
String source = uri.toString();
Drawable d = ImageHelper.decodeImage(getContext(), -1, source, true, 0, 1.0f, etText);

View File

@ -532,7 +532,7 @@ public class FragmentCompose extends FragmentBase {
setZoom();
SpannableStringBuilder hint = new SpannableStringBuilder();
SpannableStringBuilder hint = new SpannableStringBuilderEx();
hint.append(getString(R.string.title_body_hint));
hint.append("\n");
int pos = hint.length();
@ -1910,7 +1910,7 @@ public class FragmentCompose extends FragmentBase {
if (BuildConfig.DEBUG) {
SubMenu profiles = main.addSubMenu(Menu.NONE, order, order++, "Profiles");
for (EmailProvider p : EmailProvider.loadProfiles(getContext())) {
SpannableStringBuilder ssb = new SpannableStringBuilder();
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
int start;
ssb.append("IMAP (account, receive)");
@ -2755,7 +2755,7 @@ public class FragmentCompose extends FragmentBase {
CharSequence body = args.getCharSequence("body");
int start = args.getInt("start");
SpannableStringBuilder s = new SpannableStringBuilder(body);
SpannableStringBuilder s = new SpannableStringBuilderEx(body);
if (start < 0)
start = 0;
if (start > s.length())
@ -6118,7 +6118,7 @@ public class FragmentCompose extends FragmentBase {
}
}, null);
SpannableStringBuilder bodyBuilder = new SpannableStringBuilder(spannedBody);
SpannableStringBuilder bodyBuilder = new SpannableStringBuilderEx(spannedBody);
QuoteSpan[] bodySpans = bodyBuilder.getSpans(0, bodyBuilder.length(), QuoteSpan.class);
for (QuoteSpan quoteSpan : bodySpans) {
QuoteSpan q;

View File

@ -641,7 +641,7 @@ public class FragmentDialogOpenLink extends FragmentDialogBase {
String scheme = uri.getScheme();
String host = uri.getHost();
String text = uri.toString();
SpannableStringBuilder ssb = new SpannableStringBuilder(text);
SpannableStringBuilder ssb = new SpannableStringBuilderEx(text);
try {
int textColorLink = Helper.resolveColor(context, android.R.attr.textColorLink);

View File

@ -4640,7 +4640,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), vwAnchor);
SpannableStringBuilder all = new SpannableStringBuilder(getString(R.string.title_language_all));
SpannableStringBuilder all = new SpannableStringBuilderEx(getString(R.string.title_language_all));
if (current == null) {
all.setSpan(new StyleSpan(Typeface.BOLD), 0, all.length(), 0);
all.setSpan(new RelativeSizeSpan(HtmlHelper.FONT_LARGE), 0, all.length(), 0);
@ -4651,7 +4651,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences.
for (int i = 0; i < locales.size(); i++) {
Locale locale = locales.get(i);
String language = locale.getLanguage();
SpannableStringBuilder title = new SpannableStringBuilder(locale.getDisplayLanguage());
SpannableStringBuilder title = new SpannableStringBuilderEx(locale.getDisplayLanguage());
if (language.equals(current)) {
title.setSpan(new StyleSpan(Typeface.BOLD), 0, title.length(), 0);
title.setSpan(new RelativeSizeSpan(HtmlHelper.FONT_LARGE), 0, title.length(), 0);

View File

@ -220,7 +220,7 @@ public class FragmentOptions extends FragmentBase {
for (int i = 0; i < tabLayout.getTabCount(); i++) {
Drawable d = context.getDrawable(PAGE_ICONS[i]);
d.setColorFilter(colorAccent, PorterDuff.Mode.SRC_ATOP);
SpannableStringBuilder title = new SpannableStringBuilder(getString(PAGE_TITLES[i]));
SpannableStringBuilder title = new SpannableStringBuilderEx(getString(PAGE_TITLES[i]));
if (i > 0)
title.setSpan(new RelativeSizeSpan(0.85f), 0, title.length(), 0);
tabLayout.getTabAt(i)

View File

@ -416,7 +416,7 @@ public class FragmentOptionsEncryption extends FragmentBase implements SharedPre
@Override
protected Spanned onExecute(Context context, Bundle args) {
boolean debug = args.getBoolean("debug");
SpannableStringBuilder ssb = new SpannableStringBuilder();
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
int dp24 = Helper.dp2pixels(context, 24);

View File

@ -1189,7 +1189,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
try {
int start = 0;
int dp24 = Helper.dp2pixels(getContext(), 24);
SpannableStringBuilder ssb = new SpannableStringBuilder();
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
PackageManager pm = getContext().getPackageManager();
PackageInfo pi = pm.getPackageInfo(BuildConfig.APPLICATION_ID, PackageManager.GET_PERMISSIONS);
for (int i = 0; i < pi.requestedPermissions.length; i++) {

View File

@ -159,7 +159,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc
List<CharSequence> fn = new ArrayList<>();
for (int i = 0; i < fontNameNames.length; i++) {
SpannableStringBuilder ssb = new SpannableStringBuilder(fontNameNames[i]);
SpannableStringBuilder ssb = new SpannableStringBuilderEx(fontNameNames[i]);
ssb.setSpan(new TypefaceSpan(fontNameValues[i]), 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
fn.add(ssb);
}

View File

@ -2260,7 +2260,7 @@ public class HtmlHelper {
}
static Spanned highlightHeaders(Context context, String headers, boolean blocklist) {
SpannableStringBuilder ssb = new SpannableStringBuilder(headers);
SpannableStringBuilder ssb = new SpannableStringBuilderEx(headers);
int textColorLink = Helper.resolveColor(context, android.R.attr.textColorLink);
int index = 0;
@ -2584,7 +2584,7 @@ public class HtmlHelper {
}, document.body());
// https://developer.android.com/guide/topics/text/spans
SpannableStringBuilder ssb = new SpannableStringBuilder();
SpannableStringBuilder ssb = new SpannableStringBuilderEx();
NodeTraversor.traverse(new NodeVisitor() {
private Element element;

View File

@ -131,7 +131,7 @@ public class PopupMenuLifecycle extends PopupMenu implements LifecycleObserver {
icon.setBounds(0, 0, iconSize, iconSize);
ImageSpan imageSpan = new CenteredImageSpan(icon);
SpannableStringBuilder ssb = new SpannableStringBuilder(menuItem.getTitle());
SpannableStringBuilder ssb = new SpannableStringBuilderEx(menuItem.getTitle());
ssb.insert(0, "\uFFFC\u2002"); // object replacement character, en space
ssb.setSpan(imageSpan, 0, 1, 0);
menuItem.setTitle(ssb);

View File

@ -0,0 +1,70 @@
package eu.faircode.email;
/*
This file is part of FairEmail.
FairEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FairEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018-2021 by Marcel Bokhorst (M66B)
*/
import android.text.SpannableStringBuilder;
public class SpannableStringBuilderEx extends SpannableStringBuilder {
public SpannableStringBuilderEx() {
super();
}
public SpannableStringBuilderEx(CharSequence text) {
super(text);
}
public SpannableStringBuilderEx(CharSequence text, int start, int end) {
super(text, start, end);
}
@Override
public void setSpan(Object what, int start, int end, int flags) {
try {
super.setSpan(what, start, end, flags);
} catch (Throwable ex) {
Log.e(ex);
/*
java.lang.IndexOutOfBoundsException: setSpan (-1 ... -1) starts before 0
at android.text.SpannableStringInternal.checkRange(SpannableStringInternal.java:497)
at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:197)
at android.text.SpannableStringInternal.setSpan(SpannableStringInternal.java:184)
at android.text.SpannableString.setSpan(SpannableString.java:60)
at android.text.Selection.setSelection(Selection.java:96)
at android.text.Selection.setSelection(Selection.java:78)
at android.widget.Editor$SelectionStartHandleView.updateSelection(Editor.java:7649)
at android.widget.Editor$HandleView.positionAtCursorOffset(Editor.java:6886)
at android.widget.Editor$HandleView.updatePosition(Editor.java:6920)
at android.widget.Editor$PositionListener.onPreDraw(Editor.java:3660)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1093)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3194)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2046)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8349)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1058)
at android.view.Choreographer.doCallbacks(Choreographer.java:880)
at android.view.Choreographer.doFrame(Choreographer.java:813)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1043)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7861)
*/
}
}
}

View File

@ -146,7 +146,7 @@ public class StyleHelper {
int[] titles = new int[]{R.string.title_style_size_small, R.string.title_style_size_medium, R.string.title_style_size_large};
float[] sizes = new float[]{HtmlHelper.FONT_SMALL, 1.0f, HtmlHelper.FONT_LARGE};
for (int i = 0; i < ids.length; i++) {
SpannableStringBuilder ssb = new SpannableStringBuilder(context.getString(titles[i]));
SpannableStringBuilder ssb = new SpannableStringBuilderEx(context.getString(titles[i]));
ssb.setSpan(new RelativeSizeSpan(sizes[i]), 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
smenu.add(R.id.group_style_size, ids[i], i, ssb);
}
@ -156,7 +156,7 @@ public class StyleHelper {
String[] fontNameValues = anchor.getResources().getStringArray(R.array.fontNameValues);
SubMenu smenu = popupMenu.getMenu().findItem(R.id.menu_style_font).getSubMenu();
for (int i = 0; i < fontNameNames.length; i++) {
SpannableStringBuilder ssb = new SpannableStringBuilder(fontNameNames[i]);
SpannableStringBuilder ssb = new SpannableStringBuilderEx(fontNameNames[i]);
ssb.setSpan(getTypefaceSpan(fontNameValues[i], context), 0, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
smenu.add(R.id.group_style_font, i, 0, ssb);
}