1
1
// This source file is part of the Swift.org open source project
2
2
//
3
- // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
3
+ // Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
4
4
// Licensed under Apache License v2.0 with Runtime Library Exception
5
5
//
6
6
// See http://swift.org/LICENSE.txt for license information
@@ -504,7 +504,7 @@ open class XMLParser : NSObject {
504
504
// If we have not received 4 bytes, save the bomChunk for next pass
505
505
if bomChunk. count < 4 {
506
506
_bomChunk = bomChunk
507
- return false
507
+ return true
508
508
}
509
509
// Prepare options (substitute entities, recover on errors)
510
510
var options = _kCFXMLInterfaceRecover | _kCFXMLInterfaceNoEnt
@@ -520,6 +520,12 @@ open class XMLParser : NSObject {
520
520
let bytes = rawBuffer. baseAddress!. assumingMemoryBound ( to: CChar . self)
521
521
_parserContext = _CFXMLInterfaceCreatePushParserCtxt ( handler, interface, bytes, 4 , nil )
522
522
}
523
+ guard _parserContext != nil else {
524
+ if _parserError == nil {
525
+ _parserError = NSError ( domain: XMLParser . errorDomain, code: ErrorCode . outOfMemoryError. rawValue)
526
+ }
527
+ return false
528
+ } ;
523
529
_CFXMLInterfaceCtxtUseOptions ( _parserContext, options)
524
530
// Prepare the remaining data for parsing
525
531
let dataRange = bomChunk. indices
@@ -540,49 +546,46 @@ open class XMLParser : NSObject {
540
546
return result
541
547
}
542
548
543
- internal func parseFromStream ( ) -> Bool {
549
+ internal func parseFrom ( _ stream : InputStream ) -> Bool {
544
550
var result = true
545
- XMLParser . setCurrentParser ( self )
546
- defer { XMLParser . setCurrentParser ( nil ) }
547
- if let stream = _stream {
548
- stream. open ( )
549
- defer { stream. close ( ) }
550
- let buffer = malloc ( _chunkSize) !. bindMemory ( to: UInt8 . self, capacity: _chunkSize)
551
- defer { free ( buffer) }
552
- var len = stream. read ( buffer, maxLength: _chunkSize)
553
- if len != - 1 {
554
- while len > 0 {
555
- let data = Data ( bytesNoCopy: buffer, count: len, deallocator: . none)
556
- result = parseData ( data)
557
- len = stream. read ( buffer, maxLength: _chunkSize)
558
- }
559
- } else {
551
+
552
+ guard let buffer = malloc ( _chunkSize) ? . bindMemory ( to: UInt8 . self, capacity: _chunkSize) else { return false }
553
+ defer { free ( buffer) }
554
+
555
+ stream. open ( )
556
+ defer { stream. close ( ) }
557
+ parseLoop: while result {
558
+ switch stream. read ( buffer, maxLength: _chunkSize) {
559
+ case let len where len > 0 :
560
+ let data = Data ( bytesNoCopy: buffer, count: len, deallocator: . none)
561
+ result = parseData ( data)
562
+ case 0 :
563
+ break parseLoop
564
+ default : // See SR-13516, should be `case ..<0:`
560
565
result = false
561
- }
562
- } else if var data = _data {
563
- let buffer = malloc ( _chunkSize) !. bindMemory ( to: UInt8 . self, capacity: _chunkSize)
564
- defer { free ( buffer) }
565
- var range = NSRange ( location: 0 , length: min ( _chunkSize, data. count) )
566
- while result {
567
- let chunk = data. withUnsafeMutableBytes { ( rawBuffer: UnsafeMutableRawBufferPointer ) -> Data in
568
- let ptr = rawBuffer. baseAddress!. advanced ( by: range. location)
569
- return Data ( bytesNoCopy: ptr, count: range. length, deallocator: . none)
570
- }
571
- result = parseData ( chunk)
572
- if range. location + range. length >= data. count {
573
- break
566
+ if _parserError == nil {
567
+ _parserError = stream. streamError
574
568
}
575
- range = NSRange ( location: range. location + range. length, length: min ( _chunkSize, data. count - ( range. location + range. length) ) )
569
+
570
+ break parseLoop
576
571
}
577
- } else {
578
- result = false
579
572
}
573
+
580
574
return result
581
575
}
582
576
583
577
// called to start the event-driven parse. Returns YES in the event of a successful parse, and NO in case of error.
584
578
open func parse( ) -> Bool {
585
- return parseFromStream ( )
579
+ XMLParser . setCurrentParser ( self )
580
+ defer { XMLParser . setCurrentParser ( nil ) }
581
+
582
+ if _stream != nil {
583
+ return parseFrom ( _stream!)
584
+ } else if _data != nil {
585
+ return parseData ( _data!)
586
+ }
587
+
588
+ return false
586
589
}
587
590
588
591
// called by the delegate to stop the parse. The delegate will get an error message sent to it.
0 commit comments