Skip to content

Commit

Permalink
Set size limit for user agent and accept language. (#493)
Browse files Browse the repository at this point in the history
  • Loading branch information
fnando committed Sep 23, 2020
1 parent a3a7a7f commit dc259a2
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
- Fix QQ detection.
- Fix Alipay detection.
- Add Sougou Browser detection.
- User agent has a size limit of 512 bytes. This can be customized through
`Browser.user_agent_size_limit`.
- Accept-Language has a size limit of 256 bytes. This can be customized through
`Browser.accept_language_size_limit`.

## 4.2.0

Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,20 @@ Rails.configuration.middleware.use Browser::Middleware do
end
```

### Restrictions

- User agent has a size limit of 512 bytes. This can be customized through
`Browser.user_agent_size_limit=(size)`.
- Accept-Language has a size limit of 256 bytes. This can be customized through
`Browser.accept_language_size_limit=(size)`.

If size is not respected, then `Browser::Error` is raised.

```ruby
Browser.user_agent_size_limit = 1024
Browser.accept_language_size_limit = 150
```

## Development

### Versioning
Expand Down
14 changes: 14 additions & 0 deletions lib/browser/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class Base
attr_reader :accept_language

def initialize(ua, accept_language: nil)
validate_size(:user_agent, ua.to_s)
validate_size(:accept_language, accept_language.to_s)

@ua = ua
@accept_language = AcceptLanguage.parse(accept_language)
end
Expand Down Expand Up @@ -251,5 +254,16 @@ def proxy?
def electron?(expected_version = nil)
Electron.new(ua).match? && detect_version?(full_version, expected_version)
end

private def validate_size(subject, input)
actual_bytesize = input.bytesize
size_limit = Browser.public_send("#{subject}_size_limit")

return if actual_bytesize < size_limit

raise Error,
"#{subject} cannot be larger than #{size_limit} bytes; " \
"actual size is #{actual_bytesize}"
end
end
end
10 changes: 10 additions & 0 deletions lib/browser/browser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,20 @@
module Browser
EMPTY_STRING = ""

Error = Class.new(StandardError)

def self.root
@root ||= Pathname.new(File.expand_path("../..", __dir__))
end

class << self
attr_accessor :user_agent_size_limit
attr_accessor :accept_language_size_limit
end

self.user_agent_size_limit = 512
self.accept_language_size_limit = 256

# Hold the list of browser matchers.
# Order is important.
def self.matchers
Expand Down
18 changes: 18 additions & 0 deletions test/browser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,22 @@ class BrowserTest < Minitest::Test
browser = Browser.new("Fancy new browser")
refute browser.known?
end

test "rejects user agent larger than 512 bytes" do
message = "user_agent cannot be larger than 512 bytes; actual size is " \
"513 bytes"

assert_raises(Browser::Error, message) do
Browser.new("a" * 513)
end
end

test "rejects accept language larger than 256 bytes" do
message = "accept_language cannot be larger than 256 bytes; actual size " \
"is 257 bytes"

assert_raises(Browser::Error, message) do
Browser.new("Chrome", accept_language: "a" * 257)
end
end
end

0 comments on commit dc259a2

Please sign in to comment.