From 998535515bae8ec5bcd2bd95bc0cf4f34416dff7 Mon Sep 17 00:00:00 2001 From: ByteHamster Date: Sat, 27 Mar 2021 22:31:10 +0100 Subject: [PATCH] Make AntennaPod pass the medium SpotBugs findings --- .../ViewPagerBottomSheetBehavior.java | 3 + .../activity/BugReportActivity.java | 5 +- .../activity/MediaplayerActivity.java | 2 - .../asynctask/DocumentFileExportWorker.java | 4 - .../antennapod/asynctask/ExportWorker.java | 4 +- .../discovery/ItunesTopListLoader.java | 10 --- .../fragment/PagedToolbarFragment.java | 9 ++- .../fragment/SubscriptionFragment.java | 3 + build.gradle | 2 +- config/spotbugs/exclude.xml | 74 +++++++++++++++++-- .../core/backup/OpmlBackupAgent.java | 2 +- .../danoeh/antennapod/core/feed/Chapter.java | 4 +- .../danoeh/antennapod/core/feed/FeedItem.java | 2 +- .../core/service/download/HttpDownloader.java | 7 +- .../playback/PlaybackServiceMediaPlayer.java | 2 +- .../core/storage/DatabaseExporter.java | 5 +- .../antennapod/core/storage/PodDBAdapter.java | 2 +- .../antennapod/core/cast/CastUtils.java | 1 - .../core/cast/MediaInfoCreator.java | 3 - .../net/ssl/BackportTrustManager.java | 4 +- 20 files changed, 103 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java index 9ed4897d2..d9b912634 100644 --- a/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java +++ b/app/src/main/java/com/google/android/material/bottomsheet/ViewPagerBottomSheetBehavior.java @@ -53,6 +53,9 @@ public class ViewPagerBottomSheetBehavior extends BottomSheetBeh } public void updateScrollingChild() { + if (viewRef == null) { + return; + } final View scrollingChild = findScrollingChild(viewRef.get()); nestedScrollingChildRef = new WeakReference<>(scrollingChild); } diff --git a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java index 721291597..50794ba5b 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java @@ -99,7 +99,10 @@ public class BugReportActivity extends AppCompatActivity { private void exportLog() { try { File filename = new File(UserPreferences.getDataFolder(null), "full-logs.txt"); - filename.createNewFile(); + boolean success = filename.createNewFile(); + if (!success) { + throw new IOException("Unable to create output file"); + } String cmd = "logcat -d -f " + filename.getAbsolutePath(); Runtime.getRuntime().exec(cmd); //share file diff --git a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java index 56a66ba93..1fcc3512d 100644 --- a/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java +++ b/app/src/main/java/de/danoeh/antennapod/activity/MediaplayerActivity.java @@ -2,7 +2,6 @@ package de.danoeh.antennapod.activity; import android.annotation.TargetApi; import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.PixelFormat; import android.os.Build; import android.os.Bundle; @@ -479,7 +478,6 @@ public abstract class MediaplayerActivity extends CastEnabledActivity implements cardViewSeek = findViewById(R.id.cardViewSeek); txtvSeek = findViewById(R.id.txtvSeek); - SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE); showTimeLeft = UserPreferences.shouldShowRemainingTime(); Log.d("timeleft", showTimeLeft ? "true" : "false"); txtvLength = findViewById(R.id.txtvLength); diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java index 906d50c61..73e19c746 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/DocumentFileExportWorker.java @@ -5,7 +5,6 @@ import android.net.Uri; import androidx.annotation.NonNull; import androidx.documentfile.provider.DocumentFile; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -37,9 +36,6 @@ public class DocumentFileExportWorker { OutputStreamWriter writer = null; try { Uri uri = output.getUri(); - if (uri == null) { - throw new FileNotFoundException("Export file not found."); - } outputStream = context.getContentResolver().openOutputStream(uri); if (outputStream == null) { throw new IOException(); diff --git a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java index 0930b59eb..af9f041af 100644 --- a/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java +++ b/app/src/main/java/de/danoeh/antennapod/asynctask/ExportWorker.java @@ -41,8 +41,8 @@ public class ExportWorker { public Observable exportObservable() { if (output.exists()) { - Log.w(TAG, "Overwriting previously exported file."); - output.delete(); + boolean success = output.delete(); + Log.w(TAG, "Overwriting previously exported file: " + success); } return Observable.create(subscriber -> { OutputStreamWriter writer = null; diff --git a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesTopListLoader.java b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesTopListLoader.java index e1034f89b..e4135fcaa 100644 --- a/app/src/main/java/de/danoeh/antennapod/discovery/ItunesTopListLoader.java +++ b/app/src/main/java/de/danoeh/antennapod/discovery/ItunesTopListLoader.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.discovery; import android.content.Context; -import android.content.SharedPreferences; import android.util.Log; import de.danoeh.antennapod.R; @@ -24,8 +23,6 @@ import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; -import static android.content.Context.MODE_PRIVATE; - public class ItunesTopListLoader { private static final String TAG = "ITunesTopListLoader"; private final Context context; @@ -38,13 +35,6 @@ public class ItunesTopListLoader { this.context = context; } - public Single> loadToplist() { - String defaultCountry = Locale.getDefault().getCountry(); - SharedPreferences prefs = context.getSharedPreferences(PREFS, MODE_PRIVATE); - String countryCode = prefs.getString(PREF_KEY_COUNTRY_CODE, COUNTRY_CODE_UNSET); - return this.loadToplist(countryCode, 25); - } - public Single> loadToplist(String country, int limit) { return Single.create((SingleOnSubscribe>) emitter -> { OkHttpClient client = AntennapodHttpClient.getHttpClient(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/PagedToolbarFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/PagedToolbarFragment.java index 2ed26b1c0..f79bffabc 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/PagedToolbarFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/PagedToolbarFragment.java @@ -1,5 +1,6 @@ package de.danoeh.antennapod.fragment; +import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.viewpager2.widget.ViewPager2; @@ -14,12 +15,12 @@ public abstract class PagedToolbarFragment extends Fragment { /** * Invalidate the toolbar menu if the current child fragment is visible. - * @param child The fragment, or null to force-refresh whatever the active fragment is. + * @param child The fragment to invalidate */ - void invalidateOptionsMenuIfActive(Fragment child) { + void invalidateOptionsMenuIfActive(@NonNull Fragment child) { Fragment visibleChild = getChildFragmentManager().findFragmentByTag("f" + viewPager.getCurrentItem()); - if (visibleChild == child || child == null) { - child.onPrepareOptionsMenu(toolbar.getMenu()); + if (visibleChild == child) { + visibleChild.onPrepareOptionsMenu(toolbar.getMenu()); } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java index 58cfece14..f6b7e74bb 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/SubscriptionFragment.java @@ -291,6 +291,9 @@ public class SubscriptionFragment extends Fragment implements Toolbar.OnMenuItem @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); + if (menuInfo == null) { + return; + } AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo; int position = adapterInfo.position; diff --git a/build.gradle b/build.gradle index 6e0ccddec..ec9148778 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ allprojects { spotbugs { effort = 'max' - reportLevel = 'high' // for now + reportLevel = 'medium' excludeFilter = rootProject.file('config/spotbugs/exclude.xml') ignoreFailures = true // Handled by printing task } diff --git a/config/spotbugs/exclude.xml b/config/spotbugs/exclude.xml index c2e97c780..c5ea5bdcf 100644 --- a/config/spotbugs/exclude.xml +++ b/config/spotbugs/exclude.xml @@ -1,16 +1,28 @@ + + + + + + + + - - + + - - + + + + + + @@ -28,12 +40,58 @@ - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java index c05e2e9f1..6ca84ff87 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java +++ b/core/src/main/java/de/danoeh/antennapod/core/backup/OpmlBackupAgent.java @@ -94,7 +94,7 @@ public class OpmlBackupAgent extends BackupAgentHelper { if (len != -1) { byte[] oldChecksum = new byte[len]; - inState.read(oldChecksum); + IOUtils.read(inState, oldChecksum, 0, len); Log.d(TAG, "Old checksum: " + new BigInteger(1, oldChecksum).toString(16)); if (Arrays.equals(oldChecksum, newChecksum)) { diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java index 08a531d17..1c13471a5 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Chapter.java @@ -43,7 +43,7 @@ public abstract class Chapter extends FeedComponent { String imageUrl = cursor.getString(indexImage); int chapterType = cursor.getInt(indexChapterType); - Chapter chapter = null; + Chapter chapter; switch (chapterType) { case SimpleChapter.CHAPTERTYPE_SIMPLECHAPTER: chapter = new SimpleChapter(start, title, link, imageUrl); @@ -54,6 +54,8 @@ public abstract class Chapter extends FeedComponent { case VorbisCommentChapter.CHAPTERTYPE_VORBISCOMMENT_CHAPTER: chapter = new VorbisCommentChapter(start, title, link, imageUrl); break; + default: + throw new IllegalArgumentException("Unknown chapter type"); } chapter.setId(id); return chapter; diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java index 47df099b5..25857dad2 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java @@ -65,7 +65,7 @@ public class FeedItem extends FeedComponent implements Serializable { * The list of chapters of this item. This might be null even if there are chapters of this item * in the database. The 'hasChapters' attribute should be used to check if this item has any chapters. * */ - private List chapters; + private transient List chapters; private String imageUrl; /* diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java index 2d955859f..5050225f7 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/HttpDownloader.java @@ -188,8 +188,11 @@ public class HttpDownloader extends Downloader { out = new RandomAccessFile(destination, "rw"); out.seek(request.getSoFar()); } else { - destination.delete(); - destination.createNewFile(); + boolean success = destination.delete(); + success |= destination.createNewFile(); + if (!success) { + throw new IOException("Unable to recreate partially downloaded file"); + } out = new RandomAccessFile(destination, "rw"); } diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java index 1f047ceee..785784497 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/playback/PlaybackServiceMediaPlayer.java @@ -217,7 +217,7 @@ public abstract class PlaybackServiceMediaPlayer { * could result in nonsensical results (like a status of PLAYING, but a null playable) * @return the current player status */ - public PlayerStatus getPlayerStatus() { + public synchronized PlayerStatus getPlayerStatus() { return playerStatus; } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java index 271babc6e..a0fac0c74 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DatabaseExporter.java @@ -91,7 +91,10 @@ public class DatabaseExporter { db.close(); File currentDB = context.getDatabasePath(PodDBAdapter.DATABASE_NAME); - currentDB.delete(); + boolean success = currentDB.delete(); + if (!success) { + throw new IOException("Unable to delete old database"); + } FileUtils.moveFile(tempDB, currentDB); } catch (IOException | SQLiteException e) { Log.e(TAG, Log.getStackTraceString(e)); diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 98d5e6310..7ab776856 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -331,7 +331,7 @@ public class PodDBAdapter { PodDBAdapter.context = context.getApplicationContext(); } - public static PodDBAdapter getInstance() { + public static synchronized PodDBAdapter getInstance() { if (instance == null) { instance = new PodDBAdapter(); } diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java index 86c85de6b..248f6dc46 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java +++ b/core/src/play/java/de/danoeh/antennapod/core/cast/CastUtils.java @@ -35,7 +35,6 @@ public class CastUtils { public static final String KEY_FEED_URL = "de.danoeh.antennapod.core.cast.FeedUrl"; public static final String KEY_FEED_WEBSITE = "de.danoeh.antennapod.core.cast.FeedWebsite"; public static final String KEY_EPISODE_NOTES = "de.danoeh.antennapod.core.cast.EpisodeNotes"; - public static final int EPISODE_NOTES_MAX_LENGTH = Integer.MAX_VALUE; /** * The field AntennaPod.FormatVersion specifies which version of MediaMetaData diff --git a/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java b/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java index 91de5418d..a9df49176 100644 --- a/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java +++ b/core/src/play/java/de/danoeh/antennapod/core/cast/MediaInfoCreator.java @@ -39,9 +39,6 @@ public class MediaInfoCreator { } String notes = media.getNotes(); if (notes != null) { - if (notes.length() > CastUtils.EPISODE_NOTES_MAX_LENGTH) { - notes = notes.substring(0, CastUtils.EPISODE_NOTES_MAX_LENGTH); - } metadata.putString(CastUtils.KEY_EPISODE_NOTES, notes); } // Default id value diff --git a/net/ssl/src/main/java/de/danoeh/antennapod/net/ssl/BackportTrustManager.java b/net/ssl/src/main/java/de/danoeh/antennapod/net/ssl/BackportTrustManager.java index 3a188b47a..cda4298fd 100644 --- a/net/ssl/src/main/java/de/danoeh/antennapod/net/ssl/BackportTrustManager.java +++ b/net/ssl/src/main/java/de/danoeh/antennapod/net/ssl/BackportTrustManager.java @@ -6,10 +6,12 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.nio.charset.Charset; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.util.ArrayList; import java.util.List; @@ -52,7 +54,7 @@ public class BackportTrustManager { managers.add(getSystemTrustManager(keystore)); managers.add(getSystemTrustManager(null)); return new CompositeX509TrustManager(managers); - } catch (Exception e) { + } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException e) { Log.e(TAG, Log.getStackTraceString(e)); return null; }