mirror of
https://github.com/github/codeql.git
synced 2025-12-18 09:43:15 +01:00
134 lines
4.5 KiB
Swift
134 lines
4.5 KiB
Swift
|
|
// --- stubs ---
|
|
|
|
struct URL
|
|
{
|
|
init?(string: String) {}
|
|
init?(string: String, relativeTo: URL?) {}
|
|
}
|
|
|
|
extension String {
|
|
init(contentsOf: URL) throws {
|
|
var data = ""
|
|
|
|
// ...
|
|
|
|
self.init(data)
|
|
}
|
|
}
|
|
|
|
public protocol Binding {}
|
|
|
|
extension String: Binding {}
|
|
|
|
class Statement {
|
|
fileprivate let connection: Connection
|
|
|
|
init(_ connection: Connection, _ SQL: String) throws { self.connection = connection}
|
|
|
|
public func bind(_ values: Binding?...) -> Statement { return self }
|
|
public func bind(_ values: [Binding?]) -> Statement { return self }
|
|
public func bind(_ values: [String: Binding?]) -> Statement { return self }
|
|
|
|
@discardableResult public func run(_ bindings: Binding?...) throws -> Statement { return self }
|
|
@discardableResult public func run(_ bindings: [Binding?]) throws -> Statement { return self }
|
|
@discardableResult public func run(_ bindings: [String: Binding?]) throws -> Statement { return self }
|
|
|
|
public func scalar(_ bindings: Binding?...) throws -> Binding? { return nil }
|
|
public func scalar(_ bindings: [Binding?]) throws -> Binding? { return nil }
|
|
public func scalar(_ bindings: [String: Binding?]) throws -> Binding? { return nil }
|
|
}
|
|
|
|
class Connection {
|
|
public func execute(_ SQL: String) throws { }
|
|
|
|
public func prepare(_ statement: String, _ bindings: Binding?...) throws -> Statement { return try Statement(self, "") }
|
|
public func prepare(_ statement: String, _ bindings: [Binding?]) throws -> Statement { return try Statement(self, "") }
|
|
public func prepare(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { return try Statement(self, "") }
|
|
|
|
@discardableResult public func run(_ statement: String, _ bindings: Binding?...) throws -> Statement { return try Statement(self, "") }
|
|
@discardableResult public func run(_ statement: String, _ bindings: [Binding?]) throws -> Statement { return try Statement(self, "") }
|
|
@discardableResult public func run(_ statement: String, _ bindings: [String: Binding?]) throws -> Statement { return try Statement(self, "") }
|
|
|
|
public func scalar(_ statement: String, _ bindings: Binding?...) throws -> Binding? { return nil }
|
|
public func scalar(_ statement: String, _ bindings: [Binding?]) throws -> Binding? { return nil }
|
|
public func scalar(_ statement: String, _ bindings: [String: Binding?]) throws -> Binding? { return nil }
|
|
}
|
|
|
|
// --- tests ---
|
|
|
|
func test_sqlite_swift_api(db: Connection) throws {
|
|
let localString = "user"
|
|
let remoteString = try String(contentsOf: URL(string: "http://example.com/")!)
|
|
let remoteNumber = Int(remoteString) ?? 0
|
|
|
|
let unsafeQuery1 = remoteString
|
|
let unsafeQuery2 = "SELECT * FROM users WHERE username='" + remoteString + "'"
|
|
let unsafeQuery3 = "SELECT * FROM users WHERE username='\(remoteString)'"
|
|
let safeQuery1 = "SELECT * FROM users WHERE username='\(localString)'"
|
|
let safeQuery2 = "SELECT * FROM users WHERE username='\(remoteNumber)'"
|
|
|
|
// --- execute ---
|
|
|
|
try db.execute(unsafeQuery1) // BAD
|
|
try db.execute(unsafeQuery2) // BAD
|
|
try db.execute(unsafeQuery3) // BAD
|
|
try db.execute(safeQuery1) // GOOD
|
|
try db.execute(safeQuery2) // GOOD
|
|
|
|
// --- prepared statements ---
|
|
|
|
let varQuery = "SELECT * FROM users WHERE username=?"
|
|
|
|
let stmt1 = try db.prepare(unsafeQuery3) // BAD
|
|
try stmt1.run()
|
|
|
|
let stmt2 = try db.prepare(varQuery, localString) // GOOD
|
|
try stmt2.run()
|
|
|
|
let stmt3 = try db.prepare(varQuery, remoteString) // GOOD
|
|
try stmt3.run()
|
|
|
|
let stmt4 = try Statement(db, localString) // GOOD
|
|
try stmt4.run()
|
|
|
|
let stmt5 = try Statement(db, remoteString) // BAD
|
|
try stmt5.run()
|
|
|
|
// --- more variants ---
|
|
|
|
let stmt6 = try db.prepare(unsafeQuery1, "") // BAD
|
|
try stmt6.run()
|
|
|
|
let stmt7 = try db.prepare(unsafeQuery1, [""]) // BAD
|
|
try stmt7.run()
|
|
|
|
let stmt8 = try db.prepare(unsafeQuery1, ["username": ""]) // BAD
|
|
try stmt8.run()
|
|
|
|
try db.run(unsafeQuery1, "") // BAD
|
|
|
|
try db.run(unsafeQuery1, [""]) // BAD
|
|
|
|
try db.run(unsafeQuery1, ["username": ""]) // BAD
|
|
|
|
try db.scalar(unsafeQuery1, "") // BAD
|
|
|
|
try db.scalar(unsafeQuery1, [""]) // BAD
|
|
|
|
try db.scalar(unsafeQuery1, ["username": ""]) // BAD
|
|
|
|
let stmt9 = try db.prepare(varQuery) // GOOD
|
|
try stmt9.bind(remoteString) // GOOD
|
|
try stmt9.bind([remoteString]) // GOOD
|
|
try stmt9.bind(["username": remoteString]) // GOOD
|
|
try stmt9.run(remoteString) // GOOD
|
|
try stmt9.run([remoteString]) // GOOD
|
|
try stmt9.run(["username": remoteString]) // GOOD
|
|
try stmt9.scalar(remoteString) // GOOD
|
|
try stmt9.scalar([remoteString]) // GOOD
|
|
try stmt9.scalar(["username": remoteString]) // GOOD
|
|
|
|
try Statement(db, remoteString).run() // BAD
|
|
}
|