Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Android] Check for text to paste before trying to retrieve data from URI #48166

Merged
merged 19 commits into from
Dec 1, 2023

Conversation

camsim99
Copy link
Contributor

@camsim99 camsim99 commented Nov 17, 2023

Adds a check to retrieve explicit text from Clipboard items via getText before attempting to retrieve data if the Clipboard item (ClipData.Item) has an associated URI. Also adds more error handling for edge cases concerning URIs (the URI not having the content scheme or being null).

Fixes flutter/flutter#74320. Some content providers will not send URIs containing the text/* pattern or have the content scheme (content://), but ultimately we should expect Clipboard items to either fall not into one of those categories or have an explicit textual value available via getText. In case this is not true, though, checks for non-content URIs and null URIs are added, as well :)

Tested on a Samsung tablet with pasting from MS Word, MS Excel, and Samsung Notes.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

// Clipboard does not contain text, so check whether or not we will be
// able to retrieve text from URI. FileNotFoundException will be thrown
// if not, and then null will be returned.
if (item.getUri() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even with the restructuring, shouldn't we be checking that the URI is non-null and also content:? We know from the docs that it's invalid to call openTypedAssetFileDescriptor and we know from the issue that calling this with at least file: will throw an exception that can potentially bring down the whole app.

Hopefully moving getText up will avoid that in most cases, but we've had a lot of weird plugin bugs over the years that are related to other apps sending us bad data (e.g., intent responses that have unexpected nulls), so it seems like we should have a defense-in-depth approach here to make sure that if someone sends us a file: URI with no text it won't throw.

Copy link
Contributor Author

@camsim99 camsim99 Nov 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that explicitly returning null in the case where the URI is null makes sense to make sure no weird errors come up like you're referencing.

In terms of adding a check for content: before calling openTypedAssetFileDescriptor, that makes sense as well; I initially assumed a FileNotFoundException would be thrown (which we catch) which does not seem to be the case (edit: I think this is the case for the text/* check actually).

I think it would also be helpful to add some logs to these new branches to make it clear why null is returned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed these comments, would you be willing to give it a second look? @stuartmorgan

// required if so.
CharSequence itemText = item.getText();

if (itemText == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonblocking nit: consider extracting uri logic into a method or methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved logic trying to extract text from URI to a new method!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undid this due to some recent changes here that actually made the new method more confusing.


@Test
public void platformPlugin_getClipboardDataIsNonNullWhenContentUriWithTextProvided()
throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can any of this setup logic be extracted into a logical helper method to share between tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved overlapping logic to setup methods!

Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

new PlatformPlugin(fakeActivity, mockPlatformChannel, mockPlatformPluginDelegate);

private ClipboardManager clipboardManager;
private ClipboardContentFormat clipboardFormat;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When possible, it's better to have stand-alone setup methods that return objects, rather than making fixtures stateful; I really like https://abseil.io/tips/122 on this topic (written for C++, but applicable to any language).

Maybe that's not possible here; it looks like a fair number of these variables are individually referenced in tests rather than only being used internally. When it's not I would actually prefer duplication in tests rather than a lot of fixture state, but I don't feel too strongly about it here so if you and @reidbaker prefer this, that's fine with me.

The one exception would be the testPlatformPlugin and testPlatformPluginWithDelegate. I feel pretty strongly that the object under test itself should not be part of the fixture whenever possible, and the fact that there are different versions here, each of which only apply to some tests, is even more indication that these aren't really part of the overall test state, but part of tests. If you want to abstract out the creation, you could always make a stand-alone getter instead. E.g.,:

private PlatformPlugin createTestPlugin(bool withDelegate) {
  if (withDelegate) {
    return new PlatformPlugin(fakeActivity, mockPlatformChannel, mockPlatformPluginDelegate);
  } else {
    return new PlatformPlugin(fakeActivity, mockPlatformChannel);
  }
}

(Or two different methods, one for delegate, one for no delegate)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay I was wondering if I went overboard :) thanks for the tips and explanation! This was good to learn.

I ended up keeping the setup method for clipboard tests (the ones related to this PR) and getting rid of the rest of the changes I made, leaving most of the duplication which is likely safer as you described.

@camsim99 camsim99 added the autosubmit Merge PR when tree becomes green via auto submit App label Dec 1, 2023
@auto-submit auto-submit bot merged commit 58502dc into flutter:main Dec 1, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Dec 1, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Dec 1, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Dec 1, 2023
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Dec 1, 2023
…139342)

flutter/engine@74d2df5...c26e6ce

2023-12-01 [email protected] Roll a new version of googletest (2021->2023). (flutter/engine#48285)
2023-12-01 [email protected] [canvaskit] Add ImageFilter.compose (flutter/engine#48546)
2023-12-01 [email protected] Avoid reloading the kernel snapshot when spawning an isolate in the same group (flutter/engine#48478)
2023-12-01 [email protected] [Android] Check for text to paste before trying to retrieve data from URI (flutter/engine#48166)
2023-11-30 [email protected] Roll Skia from 88a1bcb9e43e to 0a90c366ff87 (3 revisions) (flutter/engine#48549)
2023-11-30 [email protected] Manual roll Dart SDK to 3.3.0-174.2.beta (4 revisions) (flutter/engine#48538)
2023-11-30 [email protected] Roll Skia from db3399a541f3 to 88a1bcb9e43e (1 revision) (flutter/engine#48545)
2023-11-30 [email protected] [Windows] Begin decoupling text input plugin from the view (flutter/engine#47833)
2023-11-30 [email protected] Roll Skia from 2d236de89898 to db3399a541f3 (3 revisions) (flutter/engine#48543)
2023-11-30 [email protected] [Impeller] Add direct tesselation of circles for DrawCircle and Round end caps (flutter/engine#48103)
2023-11-30 [email protected] [canvaskit] Revert to `drawImage` rendering on Chrome 110 or earlier (flutter/engine#48515)
2023-11-30 [email protected] Roll Skia from 6b4bdebaab88 to 2d236de89898 (1 revision) (flutter/engine#48537)
2023-11-30 [email protected] [Impeller] Started expanding the blur clip region (flutter/engine#48535)
2023-11-30 [email protected] Roll Skia from 0e479728cc1f to 6b4bdebaab88 (1 revision) (flutter/engine#48536)
2023-11-30 [email protected] Roll Skia from 0968fe18ff75 to 0e479728cc1f (1 revision) (flutter/engine#48534)
2023-11-30 [email protected] Use Chromium mirror for archive dependency (flutter/engine#48509)
2023-11-30 [email protected] Roll Skia from 2f01d500a352 to 0968fe18ff75 (2 revisions) (flutter/engine#48531)
2023-11-30 [email protected] Roll Skia from 11a15444a3aa to 2f01d500a352 (1 revision) (flutter/engine#48524)
2023-11-30 [email protected] Roll Skia from 84fdd36b1eea to 11a15444a3aa (1 revision) (flutter/engine#48523)
2023-11-30 [email protected] [Android] Add support for the PlatformChannel  "Share.invoke" command (flutter/engine#48265)
2023-11-30 [email protected] Roll Skia from 5d64b1322879 to 84fdd36b1eea (1 revision) (flutter/engine#48521)
2023-11-30 [email protected] Roll Skia from 23721750e433 to 5d64b1322879 (1 revision) (flutter/engine#48520)
2023-11-30 [email protected] Roll Fuchsia Linux SDK from 8wu5EgBh1yJPNOd5W... to Bb2k375udWIltCEAx... (flutter/engine#48519)
2023-11-30 [email protected] Roll Skia from 5a635f2211ce to 23721750e433 (1 revision) (flutter/engine#48514)
2023-11-29 [email protected] Roll Skia from 928e8950e8e3 to 5a635f2211ce (1 revision) (flutter/engine#48511)
2023-11-29 [email protected] [web] No implicit view in multi-view mode (flutter/engine#48505)

Also rolling transitive DEPS:
  fuchsia/sdk/core/linux-amd64 from 8wu5EgBh1yJP to Bb2k375udWIl

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
caseycrogers pushed a commit to caseycrogers/flutter that referenced this pull request Dec 29, 2023
…lutter#139342)

flutter/engine@74d2df5...c26e6ce

2023-12-01 [email protected] Roll a new version of googletest (2021->2023). (flutter/engine#48285)
2023-12-01 [email protected] [canvaskit] Add ImageFilter.compose (flutter/engine#48546)
2023-12-01 [email protected] Avoid reloading the kernel snapshot when spawning an isolate in the same group (flutter/engine#48478)
2023-12-01 [email protected] [Android] Check for text to paste before trying to retrieve data from URI (flutter/engine#48166)
2023-11-30 [email protected] Roll Skia from 88a1bcb9e43e to 0a90c366ff87 (3 revisions) (flutter/engine#48549)
2023-11-30 [email protected] Manual roll Dart SDK to 3.3.0-174.2.beta (4 revisions) (flutter/engine#48538)
2023-11-30 [email protected] Roll Skia from db3399a541f3 to 88a1bcb9e43e (1 revision) (flutter/engine#48545)
2023-11-30 [email protected] [Windows] Begin decoupling text input plugin from the view (flutter/engine#47833)
2023-11-30 [email protected] Roll Skia from 2d236de89898 to db3399a541f3 (3 revisions) (flutter/engine#48543)
2023-11-30 [email protected] [Impeller] Add direct tesselation of circles for DrawCircle and Round end caps (flutter/engine#48103)
2023-11-30 [email protected] [canvaskit] Revert to `drawImage` rendering on Chrome 110 or earlier (flutter/engine#48515)
2023-11-30 [email protected] Roll Skia from 6b4bdebaab88 to 2d236de89898 (1 revision) (flutter/engine#48537)
2023-11-30 [email protected] [Impeller] Started expanding the blur clip region (flutter/engine#48535)
2023-11-30 [email protected] Roll Skia from 0e479728cc1f to 6b4bdebaab88 (1 revision) (flutter/engine#48536)
2023-11-30 [email protected] Roll Skia from 0968fe18ff75 to 0e479728cc1f (1 revision) (flutter/engine#48534)
2023-11-30 [email protected] Use Chromium mirror for archive dependency (flutter/engine#48509)
2023-11-30 [email protected] Roll Skia from 2f01d500a352 to 0968fe18ff75 (2 revisions) (flutter/engine#48531)
2023-11-30 [email protected] Roll Skia from 11a15444a3aa to 2f01d500a352 (1 revision) (flutter/engine#48524)
2023-11-30 [email protected] Roll Skia from 84fdd36b1eea to 11a15444a3aa (1 revision) (flutter/engine#48523)
2023-11-30 [email protected] [Android] Add support for the PlatformChannel  "Share.invoke" command (flutter/engine#48265)
2023-11-30 [email protected] Roll Skia from 5d64b1322879 to 84fdd36b1eea (1 revision) (flutter/engine#48521)
2023-11-30 [email protected] Roll Skia from 23721750e433 to 5d64b1322879 (1 revision) (flutter/engine#48520)
2023-11-30 [email protected] Roll Fuchsia Linux SDK from 8wu5EgBh1yJPNOd5W... to Bb2k375udWIltCEAx... (flutter/engine#48519)
2023-11-30 [email protected] Roll Skia from 5a635f2211ce to 23721750e433 (1 revision) (flutter/engine#48514)
2023-11-29 [email protected] Roll Skia from 928e8950e8e3 to 5a635f2211ce (1 revision) (flutter/engine#48511)
2023-11-29 [email protected] [web] No implicit view in multi-view mode (flutter/engine#48505)

Also rolling transitive DEPS:
  fuchsia/sdk/core/linux-amd64 from 8wu5EgBh1yJP to Bb2k375udWIl

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
autosubmit Merge PR when tree becomes green via auto submit App platform-android
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can't paste into TextField when copying from Samsung Notes, MS Word and MS Excel on Android
3 participants