2

I have read quite a few other SOs on this - in particular the highly-voted answer to this question: Android intent filter for a particular file extension?

My scenario is somewhat simpler - I simply want to match a particular filename on our website - e.g. http://our_domain/filename.extn - but taking into account some minor variance in case (I call this out further down).

I've written my intent-filter as follows:

<data 
  android:scheme="http"
  android:host="our_domain" 
  android:pathPattern="/filename\\.extn" />

Double-escaping the \ so that it will be read out of the XML as \., thus escaping the period so that the pattern matcher sees a literal . instead of the 'any' character.

For my tests I've written a small app that takes a string from a text box, creates an ACTION_VIEW intent with the given URI, and starts it - then checking whether the browser launches or whether I see a chooser with my app listed.

The app is correctly identified for the exact path - e.g. http://our_domain/filename.extn, but it is also being identified if I replace the . with any other character that's valid in a URI path - e.g, all of the following also trigger a match:

  • http://our_domain/filename'extn
  • http://our_domain/filename~extn
  • http://our_domain/filenameaextn

The last of which is the most worrying!

How can I set the path pattern to ensure that only a literal period matches?

Please note, I am aware that simply using path instead of pathPattern might work - however, the pattern also incorporates some minor case-insensitivity - e.g. F*f*ileN*n*ame - I have removed this stuff for the question as it makes no difference to the behaviour of this period-matching.

Is it possible that matching only literal . characters is actually not supported by the intent-filter system (not by design but by bug), and that they'll always be treated as 'any'?

Community
  • 1
  • 1
Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160

2 Answers2

2

Is it possible that matching only literal. characters is actually not supported by the intent-filter system (not by design but by bug), and that they'll always be treated as 'any'?

Yes, this looks like an android bug. I've just gone through the source code of android's PatternMatcher and this behaviour (bug?) is present to this day.

I.e. it looks like matching the . literal only works in one case - when it's preceded by a * expression. Only then it is properly escaped in code - \\ is taken into consideration). That's why people who are just trying to match a file extension are able to use a pattern like this:

<data android:pathPattern=".*\\.ext" />

As soon as the escape sequence (\\) is preceded by something else than *, the escaping is not taken into account and the dot (.) is treated as a wildcard rather than as a literal and matches any character.

I've been thinking whether I should report this bug, but it might not be worth it, considering how few people have run into it. I looked for similar SO questions, but haven't found any. Also, the . wildcard is not even mentioned as a valid wildcard in the documentation. The only valid wildcards according to the documentation are .* and *.

Jakub Kukul
  • 12,032
  • 3
  • 54
  • 53
0

Just guessing here, you might try (hack) wrapping it in [], like this: pattern="filename[.]extn", so you're only accepting characters from the following list: "." - give it a shot?

There are plenty of other regex games you could probably play, but that's the first one that comes to mind.

Travis
  • 3,737
  • 1
  • 24
  • 24
  • Unfortunately the usual regex hacks won't work - the pathPattern logic isn't even a cut-down regex engine - it just knows `.` and `*` (non-greedy). – Andras Zoltan Oct 22 '13 at 13:10