browserslist-useragent icon indicating copy to clipboard operation
browserslist-useragent copied to clipboard

Browserslist entries that have version ranges don't match valid browsers

Open litonico opened this issue 5 years ago • 4 comments

browserslist contains entries with version ranges. For instance, browserslist("ios_saf >= 9") includes the entry 'ios_saf 9.0-9.2'. For that browserslist, browserslist-useragent matches only ios_saf 9.0. User agents with iOS Safari versions of 9.1 or 9.2 are never matched.

Steps to Repro:

const { matchesUA, resolveUserAgent } = require('browserslist-useragent')
const browserslist = require('browserslist')
ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/74.0.3729.169 Mobile/13B143 Safari/601.1.46'

console.log(resolveUserAgent(ua))
// > { family: 'iOS', version: '9.1.0' } // This is correct

console.log(matchesUA(ua, { browsers: ["ios_saf >= 9"] }))
// > false // This should be `true`

Expected behavior: matchesUA('Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/74.0.3729.169 Mobile/13B143 Safari/601.1.46', { browsers: ["ios_saf >= 9"] })) returns true

Actual behavior: matchesUA('Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/74.0.3729.169 Mobile/13B143 Safari/601.1.46', { browsers: ["ios_saf >= 9"] })) returns false

What's happening:

https://github.com/browserslist/browserslist-useragent/blob/1cbab42d134df76aea5294edfacddd243fe4832f/index.js#L158

Splitting the string 'ios_saf 9.0-9.2' and taking the first array element means the only matched version is 9.0. 9.1 and 9.2 are incorrectly not matched.

litonico avatar May 30 '19 21:05 litonico

@litonico did you try allowHigherVersions option?

onoshkodaniil avatar Jul 10 '19 03:07 onoshkodaniil

@onoshkodaniil That option makes the matchesUA query correct in some cases, but that's an unrelated feature — this is still a bug. Similarly, ignoreMinor mitigates this issue, which is what we're doing in production right now. However, using that means that we are likely serving unsupported content to some users!

litonico avatar Jul 10 '19 23:07 litonico

TBH, I'm not sure why I did the split like that. It makes little sense now that I think of it. I just released 3.0.1 which should now respect version ranges instead of ignoring them (as long as the ranges are minor ranges, which seems to be true with the current output of browserslist).

Note, however, this issue is still not completely fixed due to a bug in browserslist – https://github.com/browserslist/browserslist/issues/402

pastelsky avatar Jul 31 '19 03:07 pastelsky

Hi. I still see strange behavior in 3.0.2 versions. For example:

const { matchesUA } = require("browserslist-useragent");

matchesUA("Chrome/77", { browsers: ["defaults"] }); // => return false
matchesUA("Chrome/77.0.3865.75", { browsers: ["defaults"] }); // => but this return true

cc @pastelsky

nikolay-govorov avatar Oct 02 '19 11:10 nikolay-govorov