Prevent exception from being serialized in ErrorInfo

The wrong @Decorator was put in the wrong place to mark the throwable fieldd as transient, now this is fixed and the exception is not serialized. So if a non-serializable throwable is passed, that's not an issue, since it's not going to be serialized. The need for EnsureExceptionSerializable is also gone.
This commit is contained in:
Stypox 2021-12-01 10:28:35 +01:00
parent 09d137f740
commit 397f93b079
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
7 changed files with 19 additions and 123 deletions

View File

@ -38,7 +38,6 @@ public class AcraReportSender implements ReportSender {
UserAction.UI_ERROR,
ErrorInfo.SERVICE_NONE,
"ACRA report",
R.string.app_ui_crash,
null));
R.string.app_ui_crash));
}
}

View File

@ -1,103 +0,0 @@
package org.schabi.newpipe.error;
import android.util.Log;
import androidx.annotation.NonNull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Ensures that a Exception is serializable.
* This is
*/
public final class EnsureExceptionSerializable {
private static final String TAG = "EnsureExSerializable";
private EnsureExceptionSerializable() {
// No instance
}
/**
* Ensures that an exception is serializable.
* <br/>
* If that is not the case a {@link WorkaroundNotSerializableException} is created.
*
* @param exception
* @return if an exception is not serializable a new {@link WorkaroundNotSerializableException}
* otherwise the exception from the parameter
*/
public static Exception ensureSerializable(@NonNull final Exception exception) {
return checkIfSerializable(exception)
? exception
: WorkaroundNotSerializableException.create(exception);
}
public static boolean checkIfSerializable(@NonNull final Exception exception) {
try {
// Check by creating a new ObjectOutputStream which does the serialization
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos)
) {
oos.writeObject(exception);
oos.flush();
bos.toByteArray();
}
return true;
} catch (final IOException ex) {
Log.d(TAG, "Exception is not serializable", ex);
return false;
}
}
public static class WorkaroundNotSerializableException extends Exception {
protected WorkaroundNotSerializableException(
final Throwable notSerializableException,
final Throwable cause) {
super(notSerializableException.toString(), cause);
setStackTrace(notSerializableException.getStackTrace());
}
protected WorkaroundNotSerializableException(final Throwable notSerializableException) {
super(notSerializableException.toString());
setStackTrace(notSerializableException.getStackTrace());
}
public static WorkaroundNotSerializableException create(
@NonNull final Exception notSerializableException
) {
// Build a list of the exception + all causes
final List<Throwable> throwableList = new ArrayList<>();
int pos = 0;
Throwable throwableToProcess = notSerializableException;
while (throwableToProcess != null) {
throwableList.add(throwableToProcess);
pos++;
throwableToProcess = throwableToProcess.getCause();
}
// Reverse list so that it starts with the last one
Collections.reverse(throwableList);
// Build exception stack
WorkaroundNotSerializableException cause = null;
for (final Throwable t : throwableList) {
cause = cause == null
? new WorkaroundNotSerializableException(t)
: new WorkaroundNotSerializableException(t, cause);
}
return cause;
}
}
}

View File

@ -2,6 +2,7 @@ package org.schabi.newpipe.error
import android.os.Parcelable
import androidx.annotation.StringRes
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.Info
@ -21,11 +22,14 @@ class ErrorInfo(
val userAction: UserAction,
val serviceName: String,
val request: String,
val messageStringId: Int,
@Transient // no need to store throwable, all data for report is in other variables
var throwable: Throwable? = null
val messageStringId: Int
) : Parcelable {
// no need to store throwable, all data for report is in other variables
// also, the throwable might not be serializable, see TeamNewPipe/NewPipe#7302
@IgnoredOnParcel
var throwable: Throwable? = null
private constructor(
throwable: Throwable,
userAction: UserAction,
@ -36,9 +40,10 @@ class ErrorInfo(
userAction,
serviceName,
request,
getMessageStringId(throwable, userAction),
throwable
)
getMessageStringId(throwable, userAction)
) {
this.throwable = throwable
}
private constructor(
throwable: List<Throwable>,
@ -50,9 +55,10 @@ class ErrorInfo(
userAction,
serviceName,
request,
getMessageStringId(throwable.firstOrNull(), userAction),
throwable.firstOrNull()
)
getMessageStringId(throwable.firstOrNull(), userAction)
) {
this.throwable = throwable.firstOrNull()
}
// constructors with single throwable
constructor(throwable: Throwable, userAction: UserAction, request: String) :

View File

@ -20,10 +20,6 @@ class ErrorUtil {
/**
* Reports a new error by starting a new activity.
* <br></br>
* Ensure that the data within errorInfo is serializable otherwise
* an exception will be thrown!<br></br>
* [EnsureExceptionSerializable] might help.
*
* @param context
* @param errorInfo

View File

@ -90,8 +90,7 @@ public class SubscriptionsImportFragment extends BaseFragment {
new ErrorInfo(new String[]{}, UserAction.SUBSCRIPTION_IMPORT_EXPORT,
NewPipe.getNameOfService(currentServiceId),
"Service does not support importing subscriptions",
R.string.general_error,
null));
R.string.general_error));
activity.finish();
}
}

View File

@ -12,7 +12,6 @@ import androidx.preference.PreferenceManager;
import com.google.android.exoplayer2.ExoPlaybackException;
import org.schabi.newpipe.R;
import org.schabi.newpipe.error.EnsureExceptionSerializable;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
@ -70,7 +69,7 @@ public class PlayerErrorHandler {
ErrorUtil.createNotification(
context,
new ErrorInfo(
EnsureExceptionSerializable.ensureSerializable(exception),
exception,
UserAction.PLAY_STREAM,
"Player error[type=" + exception.type + "] occurred while playing: "
+ info.getUrl(),

View File

@ -583,7 +583,7 @@ public class MissionAdapter extends Adapter<ViewHolder> implements Handler.Callb
ErrorUtil.createNotification(mContext,
new ErrorInfo(ErrorInfo.Companion.throwableToStringList(mission.errObject), action,
service, request.toString(), reason, null));
service, request.toString(), reason));
}
public void clearFinishedDownloads(boolean delete) {