浏览代码

Fix an issue causing a crash when the Content-Lenght was negative

* Add an unit tests for the new exception
* Fix an Swiftlint warning regarding the colon
* Fix a spelling error
Victor Sigler 6 年之前
父节点
当前提交
8ceaeb1925
共有 3 个文件被更改,包括 16 次插入2 次删除
  1. 7 1
      XCode/Sources/HttpParser.swift
  2. 1 1
      XCode/Sources/WebSockets.swift
  3. 8 0
      XCode/Tests/SwifterTestsHttpParser.swift

+ 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 {