diff --git a/CHANGELOG.md b/CHANGELOG.md index 7658d0de..36cebd62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ MQTT-Client-Framework iOS/OSX/tvOS Release Notes ================================================ +## MQTT-Client-Framework 0.6.3 +> Release date 2016-01-17 + +[FIX] Ignore incoming non-UTF8 topic string closes #94 +[FIX] Crash b/c input stream not closed in timeout situation closes #93 + ## MQTT-Client-Framework 0.6.2 > Release date 2016-01-05 diff --git a/MQTTClient.podspec b/MQTTClient.podspec index b60adf2f..aef91800 100644 --- a/MQTTClient.podspec +++ b/MQTTClient.podspec @@ -1,13 +1,13 @@ Pod::Spec.new do |mqttc| mqttc.name = "MQTTClient" - mqttc.version = "0.6.2" + mqttc.version = "0.6.3" mqttc.summary = "iOS, OSX and tvOS native ObjectiveC MQTT Client Framework" mqttc.homepage = "https://github.com/ckrey/MQTT-Client-Framework" mqttc.license = { :type => "EPLv1", :file => "LICENSE" } mqttc.author = { "Christoph Krey" => "krey.christoph@gmail.com" } mqttc.source = { :git => "https://github.com/ckrey/MQTT-Client-Framework.git", - :tag => "0.6.2", + :tag => "0.6.3", :submodules => true } diff --git a/MQTTClient/MQTTClient/MQTTCFSocketDecoder.m b/MQTTClient/MQTTClient/MQTTCFSocketDecoder.m index e3f4f8d9..95fc3aaa 100644 --- a/MQTTClient/MQTTClient/MQTTCFSocketDecoder.m +++ b/MQTTClient/MQTTClient/MQTTCFSocketDecoder.m @@ -47,12 +47,9 @@ - (void)open { } - (void)close { - if (self.state == MQTTCFSocketDecoderStateReady || self.state == MQTTCFSocketDecoderStateError) { - [self.stream close]; - [self.stream removeFromRunLoop:self.runLoop forMode:self.runLoopMode]; - [self.stream setDelegate:nil]; - self.state = MQTTCFSocketDecoderStateInitializing; - } + [self.stream close]; + [self.stream removeFromRunLoop:self.runLoop forMode:self.runLoopMode]; + [self.stream setDelegate:nil]; } - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { @@ -62,7 +59,7 @@ - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { self.state = MQTTCFSocketDecoderStateReady; [self.delegate decoderDidOpen:self]; } - + if (eventCode & NSStreamEventHasBytesAvailable) { DDLogVerbose(@"[MQTTCFSocketDecoder] NSStreamEventHasBytesAvailable"); if (self.state == MQTTCFSocketDecoderStateInitializing) { diff --git a/MQTTClient/MQTTClient/MQTTSession.m b/MQTTClient/MQTTClient/MQTTSession.m index fd8ffdb8..df8ef4b9 100644 --- a/MQTTClient/MQTTClient/MQTTSession.m +++ b/MQTTClient/MQTTClient/MQTTSession.m @@ -679,6 +679,11 @@ - (void)handlePublish:(MQTTMessage*)msg { NSData *topicData = [data subdataWithRange:NSMakeRange(2, topicLength)]; NSString *topic = [[NSString alloc] initWithData:topicData encoding:NSUTF8StringEncoding]; + if (!topic) { + topic = [[NSString alloc] initWithData:topicData + encoding:NSISOLatin1StringEncoding]; + DDLogError(@"non UTF8 topic %@", topic); + } NSRange range = NSMakeRange(2 + topicLength, [data length] - topicLength - 2); data = [data subdataWithRange:range]; if ([msg qos] == 0) { diff --git a/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m b/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m index c2a6cd2e..1782cfcd 100644 --- a/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m +++ b/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m @@ -116,6 +116,30 @@ - (void)testPublish_r0_q0_0xD800_MQTT_1_5_3_1 { [self testPublishCloseExpected:[@(__FUNCTION__) dataUsingEncoding:NSUTF8StringEncoding] onTopic:stringWithD800 retain:NO + atLevel:MQTTQosLevelExactlyOnce]; + [self shutdown:parameters]; + } +} + +/* + * [MQTT-1.5.3-1] + * The character data in a UTF-8 encoded string MUST be well-formed UTF-8 as defined by the + * Unicode specification [Unicode] and restated in RFC 3629 [RFC3629]. In particular this data MUST NOT + * include encodings of code points between U+D800 and U+DFFF. If a Server or Client receives a Control + * Packet containing ill-formed UTF-8 it MUST close the Network Connection. + */ +- (void)testPublish_r0_q0_0x9c_MQTT_1_5_3_1 { + NSData *data = [NSData dataWithBytes:"MQTTClient/abc\x9c\x9dxyz" length:19]; + NSString *stringWith9c = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding]; + DDLogVerbose(@"stringWithNull(%lu) %@", (unsigned long)stringWith9c.length, stringWith9c.description); + + for (NSString *broker in self.brokers.allKeys) { + DDLogVerbose(@"testing broker %@", broker); + NSDictionary *parameters = self.brokers[broker]; + [self connect:parameters]; + [self testPublishCloseExpected:[@(__FUNCTION__) dataUsingEncoding:NSUTF8StringEncoding] + onTopic:stringWith9c + retain:TRUE atLevel:MQTTQosLevelAtMostOnce]; [self shutdown:parameters]; }