Ver Fonte

Merge pull request #457 from Vkt0r/content-length

Fix an issue causing a crash when the Content-Lenght was negative
Victor Sigler há 5 anos atrás
pai
commit
73b75316cf

+ 3 - 0
CHANGELOG.md

@@ -41,6 +41,9 @@ All notable changes to this project will be documented in this file. Changes not
 - Replace CircleCI for continuous integration in favor of Github Actions. ([#446](https://github.com/httpswift/swifter/pull/446)) by [@Vkt0r](https://github.com/Vkt0r)
 - Fix `SUPPORTED_PLATFORMS` for tvOS. This helps Carthage to build only the specified platform when the option `--platform` is used. ([#464](https://github.com/httpswift/swifter/pull/464)) by [@jasminlapalme](https://github.com/jasminlapalme)
 
+## Fixed
+- Fix an issue causing a crash when the `Content-Lenght` was negative. ([#457](https://github.com/httpswift/swifter/pull/457)) by [@Vkt0r](https://github.com/Vkt0r)
+
 # [1.4.7] 
 
 ## Added

+ 17 - 14
Gemfile.lock

@@ -11,28 +11,29 @@ GEM
     colored2 (3.1.2)
     cork (0.3.0)
       colored2 (~> 3.1)
-    danger (6.1.0)
+    danger (8.0.5)
       claide (~> 1.0)
       claide-plugins (>= 0.9.2)
       colored2 (~> 3.1)
       cork (~> 0.1)
-      faraday (~> 0.9)
+      faraday (>= 0.9.0, < 2.0)
       faraday-http-cache (~> 2.0)
-      git (~> 1.5)
-      kramdown (~> 2.0)
+      git (~> 1.7)
+      kramdown (~> 2.3)
       kramdown-parser-gfm (~> 1.0)
       no_proxy_fix
       octokit (~> 4.7)
       terminal-table (~> 1)
-    danger-swiftlint (0.23.0)
+    danger-swiftlint (0.24.4)
       danger
       rake (> 10)
       thor (~> 0.19)
-    faraday (0.17.0)
+    faraday (1.0.1)
       multipart-post (>= 1.2, < 3)
-    faraday-http-cache (2.0.0)
-      faraday (~> 0.8)
-    git (1.5.0)
+    faraday-http-cache (2.2.0)
+      faraday (>= 0.8)
+    git (1.7.0)
+      rchardet (~> 1.8)
     kramdown (2.3.0)
       rexml
     kramdown-parser-gfm (1.1.0)
@@ -40,11 +41,13 @@ GEM
     multipart-post (2.1.1)
     nap (1.1.0)
     no_proxy_fix (0.1.2)
-    octokit (4.14.0)
+    octokit (4.18.0)
+      faraday (>= 0.9)
       sawyer (~> 0.8.0, >= 0.5.3)
     open4 (1.3.4)
-    public_suffix (4.0.1)
-    rake (13.0.0)
+    public_suffix (4.0.6)
+    rake (13.0.1)
+    rchardet (1.8.0)
     rexml (3.2.4)
     sawyer (0.8.2)
       addressable (>= 2.3.5)
@@ -52,7 +55,7 @@ GEM
     terminal-table (1.8.0)
       unicode-display_width (~> 1.1, >= 1.1.1)
     thor (0.20.3)
-    unicode-display_width (1.6.0)
+    unicode-display_width (1.7.0)
 
 PLATFORMS
   ruby
@@ -62,4 +65,4 @@ DEPENDENCIES
   danger-swiftlint
 
 BUNDLED WITH
-   1.17.2
+   1.17.3

+ 7 - 1
XCode/Sources/HttpParser.swift

@@ -7,8 +7,9 @@
 
 import Foundation
 
-enum HttpParserError: Error {
+enum HttpParserError: Error, Equatable {
     case invalidStatusLine(String)
+    case negativeContentLength
 }
 
 public class HttpParser {
@@ -29,6 +30,11 @@ public class HttpParser {
         request.queryParams = urlComponents?.queryItems?.map { ($0.name, $0.value ?? "") } ?? []
         request.headers = try readHeaders(socket)
         if let contentLength = request.headers["content-length"], let contentLengthValue = Int(contentLength) {
+            // Prevent a buffer overflow and runtime error trying to create an `UnsafeMutableBufferPointer` with
+            // a negative length
+            guard contentLengthValue >= 0 else {
+                throw HttpParserError.negativeContentLength
+            }
             request.body = try readBody(socket, size: contentLengthValue)
         }
         return request

+ 1 - 1
XCode/Sources/WebSockets.swift

@@ -233,7 +233,7 @@ public class WebSocketSession: Hashable, Equatable {
         frm.rsv3 = fst & 0x10
         guard frm.rsv1 == 0 && frm.rsv2 == 0 && frm.rsv3 == 0
             else {
-            throw WsError.protocolError("Reserved frame bit has not been negocitated.")
+            throw WsError.protocolError("Reserved frame bit has not been negociated.")
         }
         let opc = fst & 0x0F
         guard let opcode = OpCode(rawValue: opc) else {

+ 8 - 0
XCode/Tests/SwifterTestsHttpParser.swift

@@ -101,6 +101,14 @@ class SwifterTestsHttpParser: XCTestCase {
             XCTAssert(false, "Parser should not throw any errors if there is a valid 'Content-Length' header.")
         }
 
+        do {
+            _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\r\nContent-Length: -1\r\n\r\n"))
+        } catch let error {
+            let error = error as? HttpParserError
+            XCTAssertNotNil(error)
+            XCTAssertEqual(error!, HttpParserError.negativeContentLength)
+        }
+
         do {
             _ = try parser.readHttpRequest(TestSocket("GET / HTTP/1.0\nContent-Length: 5\n\n12345"))
         } catch {