{"action":"opened","issue":{"url":"https://api.github.com/repos/ua-parser/uap-go/issues/33","repository_url":"https://api.github.com/repos/ua-parser/uap-go","labels_url":"https://api.github.com/repos/ua-parser/uap-go/issues/33/labels{/name}","comments_url":"https://api.github.com/repos/ua-parser/uap-go/issues/33/comments","events_url":"https://api.github.com/repos/ua-parser/uap-go/issues/33/events","html_url":"https://github.com/ua-parser/uap-go/issues/33","id":170446293,"number":33,"title":"Regexes sorting is incorrect","user":{"login":"gkalabin","id":1110801,"avatar_url":"https://avatars.githubusercontent.com/u/1110801?v=3","gravatar_id":"","url":"https://api.github.com/users/gkalabin","html_url":"https://github.com/gkalabin","followers_url":"https://api.github.com/users/gkalabin/followers","following_url":"https://api.github.com/users/gkalabin/following{/other_user}","gists_url":"https://api.github.com/users/gkalabin/gists{/gist_id}","starred_url":"https://api.github.com/users/gkalabin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gkalabin/subscriptions","organizations_url":"https://api.github.com/users/gkalabin/orgs","repos_url":"https://api.github.com/users/gkalabin/repos","events_url":"https://api.github.com/users/gkalabin/events{/privacy}","received_events_url":"https://api.github.com/users/gkalabin/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-08-10T15:28:05Z","updated_at":"2016-08-10T15:28:05Z","closed_at":null,"body":"According to [specification](https://github.com/ua-parser/uap-core/blob/master/docs/specification.md#user_agent_parsers):\r\n\r\n> The list of regular-expressions regex shall be evaluated for a given user-agent string beginning with the first regex-item in the list to the last item. The first matching regex stops processing the list. Regex-matching shall be case sensitive.\r\n\r\nHere is the proof that sorting of regexes will cause wrong detection results:\r\n\r\n```GO\r\npackage main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"log\"\r\n\r\n\t\"github.com/uap-go/uaparser\"\r\n)\r\n\r\nconst (\r\n\t// specificUA is matched by X and Y, X preceeds Y in regex list\r\n\tspecificUA = \"Opera/9.80 (VRE; Opera Mini/4.2/28.2794; U; en) Presto/2.8.119 Version/11.10\"\r\n\t// broadUA is matched by Y\r\n\tbroadUA    = \"Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.5.24 Version/10.53\"\r\n)\r\n\r\nfunc main() {\r\n\tsortThreshold := 100001\r\n\tparser, err := uaparser.NewWithOptions(\"./uap-core/regexes.yaml\", uaparser.EUserAgentLookUpMode, sortThreshold, 0, true, true)\r\n\tif err != nil {\r\n\t\tlog.Fatal(err)\r\n\t}\r\n\r\n\t// specificUA is matched by X, everything is fine\r\n\tbeforeSort := parser.Parse(specificUA).UserAgent\r\n\r\n\t// cause regexes sort by parsing broadUA many times: it will cause bubbling up of regex Y\r\n\tfor i := 0; i < sortThreshold; i++ {\r\n\t\tparser.Parse(broadUA)\r\n\t}\r\n\r\n\t// specificUA is now matched by Y which bubbled up after sort. This causes wrong parsing results\r\n\tafterSort := parser.Parse(specificUA).UserAgent\r\n\tfmt.Printf(\"before sort:\\t %#v\\n after sort:\\t %#v\\n\", beforeSort, afterSort)\r\n}\r\n```\r\n\r\nResult:\r\n\r\n```\r\n$ go run test.go \r\n2016-08-10 18:21:37.284461949 +0300 MSK\tSorting UserAgents slice\r\nbefore sort:\t &uaparser.UserAgent{Family:\"Opera Mini\", Major:\"4\", Minor:\"2\", Patch:\"\"}\r\n after sort:\t &uaparser.UserAgent{Family:\"Opera\", Major:\"11\", Minor:\"10\", Patch:\"\"}\r\n```"}}
{"actor":{"display_login":"gkalabin"}}