     // MARK: - Bytes
     /// Copies a number of bytes from the start of the data object into a given buffer.
     open func getBytes(_ buffer: UnsafeMutableRawPointer, length: Int) {
-        let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: length)
-        CFDataGetBytes(_cfObject, CFRangeMake(0, length), bytePtr)
+        if funnelsAreAbstract {
+            let actualCount = Swift.min(length, self.length)
+            let sourceBuffer = UnsafeRawBufferPointer(start: bytes, count: actualCount)
+            let destinationBuffer = UnsafeMutableRawBufferPointer(start: buffer, count: actualCount)
+            sourceBuffer.copyBytes(to: destinationBuffer)
+        } else {
+            let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: length)
+            CFDataGetBytes(_cfObject, CFRangeMake(0, length), bytePtr)
+        }
     }
 
     /// Copies a range of bytes from the data object into a given buffer.
     open func getBytes(_ buffer: UnsafeMutableRawPointer, range: NSRange) {
-        let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: range.length)
-        CFDataGetBytes(_cfObject, CFRangeMake(range.location, range.length), bytePtr)
+        if funnelsAreAbstract {
+            precondition(range.location >= 0 && range.length >= 0)
+            let actualCount = Swift.min(range.length, self.length - range.location)
+            let sourceBuffer = UnsafeRawBufferPointer(start: bytes.advanced(by: range.location), count: actualCount)
+            let destinationBuffer = UnsafeMutableRawBufferPointer(start: buffer, count: actualCount)
+            sourceBuffer.copyBytes(to: destinationBuffer)
+        } else {
+            let bytePtr = buffer.bindMemory(to: UInt8.self, capacity: range.length)
+            CFDataGetBytes(_cfObject, CFRangeMake(range.location, range.length), bytePtr)
+        }
     }
 
     /// Returns a new data object containing the data object's bytes that fall within the limits specified by a given range.

    // MARK: - Mutability
    /// Appends to the data object a given number of bytes from a given buffer.
    open func append(_ bytes: UnsafeRawPointer, length: Int) {
        let bytePtr = bytes.bindMemory(to: UInt8.self, capacity: length)
        CFDataAppendBytes(_cfMutableObject, bytePtr, length)
    }

    /// Appends the content of another data object to the data object.

    // MARK: - Funnel Methods
    /// A pointer to the data contained by the mutable data object.
    open var mutableBytes: UnsafeMutableRawPointer {
        requireFunnelOverridden()
        return UnsafeMutableRawPointer(CFDataGetMutableBytePtr(_cfMutableObject))
    }

    /// The number of bytes contained in the mutable data object.
    open override var length: Int {
        get {
            requireFunnelOverridden()
            return CFDataGetLength(_cfObject)
        }
        set {
            requireFunnelOverridden()
            CFDataSetLength(_cfMutableObject, newValue)
        }
    }
