diff --git a/lib/rack/common_logger.rb b/lib/rack/common_logger.rb index 53f42cc50..6235cef24 100644 --- a/lib/rack/common_logger.rb +++ b/lib/rack/common_logger.rb @@ -65,6 +65,8 @@ def log(env, status, response_headers, began_at) length, Utils.clock_time - began_at) + msg.gsub!(/[^[:print:]\n]/) { |c| "\\x#{c.ord}" } + logger = @logger || request.get_header(RACK_ERRORS) # Standard library logger doesn't support write but it supports << which actually # calls to write on the log device without formatting diff --git a/lib/rack/lint.rb b/lib/rack/lint.rb index f451302c1..a4b34196e 100755 --- a/lib/rack/lint.rb +++ b/lib/rack/lint.rb @@ -347,7 +347,7 @@ def check_environment(env) ## * The REQUEST_METHOD must be a valid token. unless env[REQUEST_METHOD] =~ /\A[0-9A-Za-z!\#$%&'*+.^_`|~-]+\z/ - raise LintError, "REQUEST_METHOD unknown: #{env[REQUEST_METHOD]}" + raise LintError, "REQUEST_METHOD unknown: #{env[REQUEST_METHOD].dump}" end ## * The SCRIPT_NAME, if non-empty, must start with / diff --git a/test/spec_common_logger.rb b/test/spec_common_logger.rb index 56495e6ca..f5f182aa8 100644 --- a/test/spec_common_logger.rb +++ b/test/spec_common_logger.rb @@ -25,6 +25,10 @@ [200, { "content-type" => "text/html", "content-length" => "0" }, []]} + app_without_lint = lambda { |env| + [200, + { "content-type" => "text/html", "content-length" => length.to_s }, + [obj]]} it "log to rack.errors by default" do res = Rack::MockRequest.new(Rack::CommonLogger.new(app)).get("/") @@ -103,6 +107,14 @@ def with_mock_time(t = 0) (0..1).must_include duration.to_f end + it "escapes non printable characters except newline" do + logdev = StringIO.new + log = Logger.new(logdev) + Rack::MockRequest.new(Rack::CommonLogger.new(app_without_lint, log)).request("GET\b", "/hello") + + logdev.string.must_match(/GET\\x8 \/hello HTTP\/1\.1/) + end + it "log path with PATH_INFO" do logdev = StringIO.new log = Logger.new(logdev) diff --git a/test/spec_lint.rb b/test/spec_lint.rb index 4a9eac262..2242b1f98 100755 --- a/test/spec_lint.rb +++ b/test/spec_lint.rb @@ -212,6 +212,11 @@ def obj.fatal(*) end }.must_raise(Rack::Lint::LintError). message.must_match(/REQUEST_METHOD/) + lambda { + Rack::Lint.new(nil).call(env("REQUEST_METHOD" => "OOPS?\b!")) + }.must_raise(Rack::Lint::LintError). + message.must_match(/OOPS\?\\/) + lambda { Rack::Lint.new(nil).call(env("SCRIPT_NAME" => "howdy")) }.must_raise(Rack::Lint::LintError).