Use dot syntax

This commit is contained in:
Jonathan Schleifer 2019-03-16 21:58:13 +01:00
parent 8d016d961d
commit 781af5edef
No known key found for this signature in database
GPG key ID: 79D21189A2D4708D
21 changed files with 396 additions and 392 deletions

View file

@ -147,7 +147,7 @@ OF_ASSUME_NONNULL_BEGIN
*/ */
@interface XMPPConnection: OFObject @interface XMPPConnection: OFObject
{ {
OF_KINDOF(OFTCPSocket *) _socket; OFTCPSocket *_socket;
char _buffer[XMPP_CONNECTION_BUFFER_LENGTH]; char _buffer[XMPP_CONNECTION_BUFFER_LENGTH];
OFXMLParser *_parser, *_oldParser; OFXMLParser *_parser, *_oldParser;
OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder; OFXMLElementBuilder *_elementBuilder, *_oldElementBuilder;
@ -235,7 +235,7 @@ OF_ASSUME_NONNULL_BEGIN
/*! /*!
* @brief The socket used for the connection. * @brief The socket used for the connection.
*/ */
@property (readonly, nonatomic) OF_KINDOF(OFTCPSocket *) socket; @property (readonly, nonatomic) OFTCPSocket *socket;
/*! /*!
* @brief Whether encryption is required. * @brief Whether encryption is required.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018 * Copyright (c) 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018, 2019
* Jonathan Schleifer <js@heap.zone> * Jonathan Schleifer <js@heap.zone>
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
* *
@ -143,7 +143,7 @@
char *node; char *node;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([username UTF8String], &node, if ((rc = stringprep_profile(username.UTF8String, &node,
"SASLprep", 0)) != STRINGPREP_OK) "SASLprep", 0)) != STRINGPREP_OK)
@throw [XMPPStringPrepFailedException @throw [XMPPStringPrepFailedException
exceptionWithConnection: self exceptionWithConnection: self
@ -169,7 +169,7 @@
char *res; char *res;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([resource UTF8String], &res, if ((rc = stringprep_profile(resource.UTF8String, &res,
"Resourceprep", 0)) != STRINGPREP_OK) "Resourceprep", 0)) != STRINGPREP_OK)
@throw [XMPPStringPrepFailedException @throw [XMPPStringPrepFailedException
exceptionWithConnection: self exceptionWithConnection: self
@ -208,7 +208,7 @@
char *srv; char *srv;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([domain UTF8String], &srv, if ((rc = stringprep_profile(domain.UTF8String, &srv,
"Nameprep", 0)) != STRINGPREP_OK) "Nameprep", 0)) != STRINGPREP_OK)
@throw [XMPPStringPrepFailedException @throw [XMPPStringPrepFailedException
exceptionWithConnection: self exceptionWithConnection: self
@ -239,7 +239,7 @@
char *pass; char *pass;
Stringprep_rc rc; Stringprep_rc rc;
if ((rc = stringprep_profile([password UTF8String], &pass, if ((rc = stringprep_profile(password.UTF8String, &pass,
"SASLprep", 0)) != STRINGPREP_OK) "SASLprep", 0)) != STRINGPREP_OK)
@throw [XMPPStringPrepFailedException @throw [XMPPStringPrepFailedException
exceptionWithConnection: self exceptionWithConnection: self
@ -257,13 +257,13 @@
[old release]; [old release];
} }
- (void)socket: (OF_KINDOF(OFTCPSocket *))sock - (void)socket: (OFTCPSocket *)sock
didConnectToHost: (OFString *)host didConnectToHost: (OFString *)host
port: (uint16_t)port port: (uint16_t)port
exception: (id)exception exception: (id)exception
{ {
if (exception != nil) { if (exception != nil) {
if ([_nextSRVRecords count] > 0) { if (_nextSRVRecords.count > 0) {
[self xmpp_tryNextSRVRecord]; [self xmpp_tryNextSRVRecord];
return; return;
} }
@ -286,13 +286,13 @@
OFSRVDNSResourceRecord *record = OFSRVDNSResourceRecord *record =
[[[_nextSRVRecords objectAtIndex: 0] copy] autorelease]; [[[_nextSRVRecords objectAtIndex: 0] copy] autorelease];
if ([_nextSRVRecords count] == 0) { if (_nextSRVRecords.count == 0) {
[_nextSRVRecords release]; [_nextSRVRecords release];
_nextSRVRecords = nil; _nextSRVRecords = nil;
} }
[_socket asyncConnectToHost: [record target] [_socket asyncConnectToHost: record.target
port: [record port]]; port: record.port];
} }
- (void)resolver: (OFDNSResolver *)resolver - (void)resolver: (OFDNSResolver *)resolver
@ -312,7 +312,7 @@
return; return;
} }
for (OF_KINDOF(OFDNSResourceRecord *) record in for (OFDNSResourceRecord *record in
[answerRecords objectForKey: domainName]) [answerRecords objectForKey: domainName])
if ([record isKindOfClass: [OFSRVDNSResourceRecord class]]) if ([record isKindOfClass: [OFSRVDNSResourceRecord class]])
[records addObject: record]; [records addObject: record];
@ -320,7 +320,7 @@
/* TODO: Sort records */ /* TODO: Sort records */
[records makeImmutable]; [records makeImmutable];
if ([records count] == 0) { if (records.count == 0) {
/* Fall back to A / AAAA record. */ /* Fall back to A / AAAA record. */
[_socket asyncConnectToHost: _domainToASCII [_socket asyncConnectToHost: _domainToASCII
port: _port]; port: _port];
@ -341,7 +341,7 @@
@throw [OFAlreadyConnectedException exception]; @throw [OFAlreadyConnectedException exception];
_socket = [[OFTCPSocket alloc] init]; _socket = [[OFTCPSocket alloc] init];
[(OFTCPSocket *)_socket setDelegate: self]; [_socket setDelegate: self];
if (_server != nil) if (_server != nil)
[_socket asyncConnectToHost: _server [_socket asyncConnectToHost: _server
@ -362,7 +362,7 @@
- (bool)xmpp_parseBuffer: (const void *)buffer - (bool)xmpp_parseBuffer: (const void *)buffer
length: (size_t)length length: (size_t)length
{ {
if ([_socket isAtEndOfStream]) { if (_socket.atEndOfStream) {
[_delegates broadcastSelector: @selector(connectionWasClosed: [_delegates broadcastSelector: @selector(connectionWasClosed:
error:) error:)
withObject: self withObject: self
@ -448,23 +448,24 @@
X509Certificate *cert; X509Certificate *cert;
OFDictionary *SANs; OFDictionary *SANs;
bool serviceSpecific = false; bool serviceSpecific = false;
SSLSocket *socket = (SSLSocket *)_socket;
@try { @try {
[_socket verifyPeerCertificate]; [socket verifyPeerCertificate];
} @catch (SSLInvalidCertificateException *e) { } @catch (SSLInvalidCertificateException *e) {
if (reason != NULL) if (reason != NULL)
*reason = [[[e reason] copy] autorelease]; *reason = e.reason;
return false; return false;
} }
cert = [_socket peerCertificate]; cert = socket.peerCertificate;
SANs = [cert subjectAlternativeName]; SANs = cert.subjectAlternativeName;
if ([[SANs objectForKey: @"otherName"] if ([[SANs objectForKey: @"otherName"]
objectForKey: OID_SRVName] != nil || objectForKey: OID_SRVName] != nil ||
[SANs objectForKey: @"dNSName"] != nil || [SANs objectForKey: @"dNSName"] != nil ||
[SANs objectForKey: @"uniformResourceIdentifier"] != nil) [SANs objectForKey: @"uniformResourceIdentifier"] != nil)
serviceSpecific = true; serviceSpecific = true;
if ([cert hasSRVNameMatchingDomain: _domainToASCII if ([cert hasSRVNameMatchingDomain: _domainToASCII
@ -485,7 +486,7 @@
withObject: self withObject: self
withObject: element]; withObject: element];
[_socket writeString: [element XMLString]]; [_socket writeString: element.XMLString];
} }
- (void)sendIQ: (XMPPIQ *)IQ - (void)sendIQ: (XMPPIQ *)IQ
@ -496,13 +497,13 @@
XMPPCallback *callback; XMPPCallback *callback;
OFString *ID, *key; OFString *ID, *key;
if ((ID = [IQ ID]) == nil) { if ((ID = IQ.ID) == nil) {
ID = [self generateStanzaID]; ID = [self generateStanzaID];
[IQ setID: ID]; IQ.ID = ID;
} }
if ((key = [[IQ to] fullJID]) == nil) if ((key = IQ.to.fullJID) == nil)
key = [_JID bareJID]; key = _JID.bareJID;
if (key == nil) // Only happens for resource bind if (key == nil) // Only happens for resource bind
key = @"bind"; key = @"bind";
key = [key stringByAppendingString: ID]; key = [key stringByAppendingString: ID];
@ -525,13 +526,13 @@
XMPPCallback *callback; XMPPCallback *callback;
OFString *ID, *key; OFString *ID, *key;
if ((ID = [IQ ID]) == nil) { if ((ID = IQ.ID) == nil) {
ID = [self generateStanzaID]; ID = [self generateStanzaID];
[IQ setID: ID]; IQ.ID = ID;
} }
if ((key = [[IQ to] fullJID]) == nil) if ((key = IQ.to.fullJID) == nil)
key = [_JID bareJID]; key = _JID.bareJID;
if (key == nil) // Connection not yet bound, can't send stanzas if (key == nil) // Connection not yet bound, can't send stanzas
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
key = [key stringByAppendingString: ID]; key = [key stringByAppendingString: ID];
@ -577,31 +578,31 @@
} }
for (OFXMLAttribute *attribute in attributes) { for (OFXMLAttribute *attribute in attributes) {
if ([[attribute name] isEqual: @"from"] && if ([attribute.name isEqual: @"from"] &&
![[attribute stringValue] isEqual: _domain]) { ![attribute.stringValue isEqual: _domain]) {
[self xmpp_sendStreamError: @"invalid-from" [self xmpp_sendStreamError: @"invalid-from"
text: nil]; text: nil];
return; return;
} }
if ([[attribute name] isEqual: @"version"] && if ([attribute.name isEqual: @"version"] &&
![[attribute stringValue] isEqual: @"1.0"]) { ![attribute.stringValue isEqual: @"1.0"]) {
[self xmpp_sendStreamError: @"unsupported-version" [self xmpp_sendStreamError: @"unsupported-version"
text: nil]; text: nil];
return; return;
} }
} }
[parser setDelegate: _elementBuilder]; parser.delegate = _elementBuilder;
} }
- (void)elementBuilder: (OFXMLElementBuilder *)builder - (void)elementBuilder: (OFXMLElementBuilder *)builder
didBuildElement: (OFXMLElement *)element didBuildElement: (OFXMLElement *)element
{ {
/* Ignore whitespace elements */ /* Ignore whitespace elements */
if ([element name] == nil) if (element.name == nil)
return; return;
[element setDefaultNamespace: XMPP_NS_CLIENT]; element.defaultNamespace = XMPP_NS_CLIENT;
[element setPrefix: @"stream" [element setPrefix: @"stream"
forNamespace: XMPP_NS_STREAM]; forNamespace: XMPP_NS_STREAM];
@ -609,16 +610,16 @@
withObject: self withObject: self
withObject: element]; withObject: element];
if ([[element namespace] isEqual: XMPP_NS_CLIENT]) if ([element.namespace isEqual: XMPP_NS_CLIENT])
[self xmpp_handleStanza: element]; [self xmpp_handleStanza: element];
if ([[element namespace] isEqual: XMPP_NS_STREAM]) if ([element.namespace isEqual: XMPP_NS_STREAM])
[self xmpp_handleStream: element]; [self xmpp_handleStream: element];
if ([[element namespace] isEqual: XMPP_NS_STARTTLS]) if ([element.namespace isEqual: XMPP_NS_STARTTLS])
[self xmpp_handleTLS: element]; [self xmpp_handleTLS: element];
if ([[element namespace] isEqual: XMPP_NS_SASL]) if ([element.namespace isEqual: XMPP_NS_SASL])
[self xmpp_handleSASL: element]; [self xmpp_handleSASL: element];
} }
@ -630,9 +631,8 @@
if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] ||
![ns isEqual: XMPP_NS_STREAM]) ![ns isEqual: XMPP_NS_STREAM])
@throw [OFMalformedXMLException exception]; @throw [OFMalformedXMLException exception];
else { else
[self close]; [self close];
}
} }
- (void)xmpp_startStream - (void)xmpp_startStream
@ -640,8 +640,8 @@
OFString *langString = @""; OFString *langString = @"";
/* Make sure we don't get any old events */ /* Make sure we don't get any old events */
[_parser setDelegate: nil]; _parser.delegate = nil;
[_elementBuilder setDelegate: nil]; _elementBuilder.delegate = nil;
/* /*
* We can't release them now, as we are currently inside them. Release * We can't release them now, as we are currently inside them. Release
@ -651,10 +651,10 @@
_oldElementBuilder = _elementBuilder; _oldElementBuilder = _elementBuilder;
_parser = [[OFXMLParser alloc] init]; _parser = [[OFXMLParser alloc] init];
[_parser setDelegate: self]; _parser.delegate = self;
_elementBuilder = [[XMPPXMLElementBuilder alloc] init]; _elementBuilder = [[XMPPXMLElementBuilder alloc] init];
[_elementBuilder setDelegate: self]; _elementBuilder.delegate = self;
if (_language != nil) if (_language != nil)
langString = [OFString stringWithFormat: @"xml:lang='%@' ", langString = [OFString stringWithFormat: @"xml:lang='%@' ",
@ -691,18 +691,18 @@
- (void)xmpp_handleStanza: (OFXMLElement *)element - (void)xmpp_handleStanza: (OFXMLElement *)element
{ {
if ([[element name] isEqual: @"iq"]) { if ([element.name isEqual: @"iq"]) {
[self xmpp_handleIQ: [XMPPIQ stanzaWithElement: element]]; [self xmpp_handleIQ: [XMPPIQ stanzaWithElement: element]];
return; return;
} }
if ([[element name] isEqual: @"message"]) { if ([element.name isEqual: @"message"]) {
[self xmpp_handleMessage: [self xmpp_handleMessage:
[XMPPMessage stanzaWithElement: element]]; [XMPPMessage stanzaWithElement: element]];
return; return;
} }
if ([[element name] isEqual: @"presence"]) { if ([element.name isEqual: @"presence"]) {
[self xmpp_handlePresence: [self xmpp_handlePresence:
[XMPPPresence stanzaWithElement: element]]; [XMPPPresence stanzaWithElement: element]];
return; return;
@ -715,12 +715,12 @@
- (void)xmpp_handleStream: (OFXMLElement *)element - (void)xmpp_handleStream: (OFXMLElement *)element
{ {
if ([[element name] isEqual: @"features"]) { if ([element.name isEqual: @"features"]) {
[self xmpp_handleFeatures: element]; [self xmpp_handleFeatures: element];
return; return;
} }
if ([[element name] isEqual: @"error"]) { if ([element.name isEqual: @"error"]) {
OFString *condition, *reason; OFString *condition, *reason;
[self close]; [self close];
@ -728,15 +728,15 @@
withObject: self withObject: self
withObject: element]; withObject: element];
condition = [[[element elementsForNamespace: condition = [[element elementsForNamespace:
XMPP_NS_XMPP_STREAM] firstObject] name]; XMPP_NS_XMPP_STREAM].firstObject name];
if (condition == nil) if (condition == nil)
condition = @"undefined"; condition = @"undefined";
reason = [[element reason = [element
elementForName: @"text" elementForName: @"text"
namespace: XMPP_NS_XMPP_STREAM] stringValue]; namespace: XMPP_NS_XMPP_STREAM].stringValue;
@throw [XMPPStreamErrorException @throw [XMPPStreamErrorException
exceptionWithConnection: self exceptionWithConnection: self
@ -750,7 +750,7 @@
- (void)xmpp_handleTLS: (OFXMLElement *)element - (void)xmpp_handleTLS: (OFXMLElement *)element
{ {
if ([[element name] isEqual: @"proceed"]) { if ([element.name isEqual: @"proceed"]) {
/* FIXME: Catch errors here */ /* FIXME: Catch errors here */
SSLSocket *newSock; SSLSocket *newSock;
@ -759,7 +759,7 @@
withObject: self]; withObject: self];
newSock = [[SSLSocket alloc] initWithSocket: _socket]; newSock = [[SSLSocket alloc] initWithSocket: _socket];
[newSock setCertificateVerificationEnabled: false]; newSock.certificateVerificationEnabled = false;
#if 0 #if 0
/* FIXME: Not yet implemented by ObjOpenSSL */ /* FIXME: Not yet implemented by ObjOpenSSL */
[newSock setCertificateFile: _certificateFile]; [newSock setCertificateFile: _certificateFile];
@ -769,7 +769,7 @@
[newSock startTLSWithExpectedHost: nil]; [newSock startTLSWithExpectedHost: nil];
[_socket release]; [_socket release];
_socket = newSock; _socket = newSock;
[(OFTCPSocket *)_socket setDelegate: self]; [_socket setDelegate: self];
_encrypted = true; _encrypted = true;
@ -783,7 +783,7 @@
return; return;
} }
if ([[element name] isEqual: @"failure"]) if ([element.name isEqual: @"failure"])
/* TODO: Find/create an exception to throw here */ /* TODO: Find/create an exception to throw here */
@throw [OFException exception]; @throw [OFException exception];
@ -792,29 +792,29 @@
- (void)xmpp_handleSASL: (OFXMLElement *)element - (void)xmpp_handleSASL: (OFXMLElement *)element
{ {
if ([[element name] isEqual: @"challenge"]) { if ([element.name isEqual: @"challenge"]) {
OFXMLElement *responseTag; OFXMLElement *responseTag;
OFData *challenge = OFData *challenge =
[OFData dataWithBase64EncodedString: [element stringValue]]; [OFData dataWithBase64EncodedString: element.stringValue];
OFData *response = [_authModule continueWithData: challenge]; OFData *response = [_authModule continueWithData: challenge];
responseTag = [OFXMLElement elementWithName: @"response" responseTag = [OFXMLElement elementWithName: @"response"
namespace: XMPP_NS_SASL]; namespace: XMPP_NS_SASL];
if (response) { if (response) {
if ([response count] == 0) if (response.count == 0)
[responseTag setStringValue: @"="]; responseTag.stringValue = @"=";
else else
[responseTag setStringValue: responseTag.stringValue =
[response stringByBase64Encoding]]; response.stringByBase64Encoding;
} }
[self sendStanza: responseTag]; [self sendStanza: responseTag];
return; return;
} }
if ([[element name] isEqual: @"success"]) { if ([element.name isEqual: @"success"]) {
[_authModule continueWithData: [OFData [_authModule continueWithData: [OFData
dataWithBase64EncodedString: [element stringValue]]]; dataWithBase64EncodedString: element.stringValue]];
[_delegates broadcastSelector: @selector( [_delegates broadcastSelector: @selector(
connectionWasAuthenticated:) connectionWasAuthenticated:)
@ -826,11 +826,11 @@
return; return;
} }
if ([[element name] isEqual: @"failure"]) { if ([element.name isEqual: @"failure"]) {
/* FIXME: Do more parsing/handling */ /* FIXME: Do more parsing/handling */
@throw [XMPPAuthFailedException @throw [XMPPAuthFailedException
exceptionWithConnection: self exceptionWithConnection: self
reason: [element XMLString]]; reason: element.XMLString];
} }
assert(0); assert(0);
@ -842,11 +842,11 @@
XMPPCallback *callback; XMPPCallback *callback;
OFString *key; OFString *key;
if ((key = [[IQ from] fullJID]) == nil) if ((key = IQ.from.fullJID) == nil)
key = [_JID bareJID]; key = _JID.bareJID;
if (key == nil) // Only happens for resource bind if (key == nil) // Only happens for resource bind
key = @"bind"; key = @"bind";
key = [key stringByAppendingString: [IQ ID]]; key = [key stringByAppendingString: IQ.ID];
if ((callback = [_callbacks objectForKey: key])) { if ((callback = [_callbacks objectForKey: key])) {
[callback runWithIQ: IQ [callback runWithIQ: IQ
@ -860,8 +860,8 @@
withObject: self withObject: self
withObject: IQ]; withObject: IQ];
if (!handled && ![[IQ type] isEqual: @"error"] && if (!handled && ![IQ.type isEqual: @"error"] &&
![[IQ type] isEqual: @"result"]) { ![IQ.type isEqual: @"result"]) {
[self sendStanza: [IQ errorIQWithType: @"cancel" [self sendStanza: [IQ errorIQWithType: @"cancel"
condition: @"service-unavailable"]]; condition: @"service-unavailable"]];
} }
@ -913,8 +913,8 @@
_supportsStreamManagement = true; _supportsStreamManagement = true;
if (mechs != nil) { if (mechs != nil) {
for (OFXMLElement *mech in [mechs children]) for (OFXMLElement *mech in mechs.children)
[mechanisms addObject: [mech stringValue]]; [mechanisms addObject: mech.stringValue];
if (_usesAnonymousAuthentication) { if (_usesAnonymousAuthentication) {
if (![mechanisms containsObject: @"ANONYMOUS"]) if (![mechanisms containsObject: @"ANONYMOUS"])
@ -993,11 +993,11 @@
[authTag addAttributeWithName: @"mechanism" [authTag addAttributeWithName: @"mechanism"
stringValue: authName]; stringValue: authName];
if (initialMessage != nil) { if (initialMessage != nil) {
if ([initialMessage count] == 0) if (initialMessage.count == 0)
[authTag setStringValue: @"="]; authTag.stringValue = @"=";
else else
[authTag setStringValue: authTag.stringValue =
[initialMessage stringByBase64Encoding]]; initialMessage.stringByBase64Encoding;
} }
[self sendStanza: authTag]; [self sendStanza: authTag];
@ -1038,11 +1038,11 @@
[error addChild: [OFXMLElement elementWithName: condition [error addChild: [OFXMLElement elementWithName: condition
namespace: XMPP_NS_XMPP_STREAM]]; namespace: XMPP_NS_XMPP_STREAM]];
if (text) if (text)
[error addChild: [OFXMLElement [error addChild: [OFXMLElement
elementWithName: @"text" elementWithName: @"text"
namespace: XMPP_NS_XMPP_STREAM namespace: XMPP_NS_XMPP_STREAM
stringValue: text]]; stringValue: text]];
[_parser setDelegate: nil]; _parser.delegate = nil;
[self sendStanza: error]; [self sendStanza: error];
[self close]; [self close];
} }
@ -1052,7 +1052,7 @@
{ {
OFXMLElement *bindElement, *JIDElement; OFXMLElement *bindElement, *JIDElement;
assert([[IQ type] isEqual: @"result"]); assert([IQ.type isEqual: @"result"]);
bindElement = [IQ elementForName: @"bind" bindElement = [IQ elementForName: @"bind"
namespace: XMPP_NS_BIND]; namespace: XMPP_NS_BIND];
@ -1061,7 +1061,7 @@
JIDElement = [bindElement elementForName: @"jid" JIDElement = [bindElement elementForName: @"jid"
namespace: XMPP_NS_BIND]; namespace: XMPP_NS_BIND];
_JID = [[XMPPJID alloc] initWithString: [JIDElement stringValue]]; _JID = [[XMPPJID alloc] initWithString: JIDElement.stringValue];
if (_needsSession) { if (_needsSession) {
[self xmpp_sendSession]; [self xmpp_sendSession];
@ -1089,7 +1089,7 @@
- (void)xmpp_handleSessionForConnection: (XMPPConnection *)connection - (void)xmpp_handleSessionForConnection: (XMPPConnection *)connection
IQ: (XMPPIQ *)IQ IQ: (XMPPIQ *)IQ
{ {
if (![[IQ type] isEqual: @"result"]) if (![IQ.type isEqual: @"result"])
OF_ENSURE(0); OF_ENSURE(0);
[_delegates broadcastSelector: @selector(connection:wasBoundToJID:) [_delegates broadcastSelector: @selector(connection:wasBoundToJID:)
@ -1103,7 +1103,7 @@
char *cDomain; char *cDomain;
Idna_rc rc; Idna_rc rc;
if ((rc = idna_to_ascii_8z([domain UTF8String], if ((rc = idna_to_ascii_8z(domain.UTF8String,
&cDomain, IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) &cDomain, IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS)
@throw [XMPPIDNATranslationFailedException @throw [XMPPIDNATranslationFailedException
exceptionWithConnection: self exceptionWithConnection: self

View file

@ -3,11 +3,13 @@
OF_ASSUME_NONNULL_BEGIN OF_ASSUME_NONNULL_BEGIN
@interface XMPPContact () @interface XMPPContact ()
- (void)xmpp_setRosterItem: (XMPPRosterItem *)rosterItem; @property (readwrite, nonatomic, setter=xmpp_setRosterItem:)
XMPPRosterItem *rosterItem;
@property OF_NULLABLE_PROPERTY (retain, nonatomic) XMPPJID *xmpp_lockedOnJID;
- (void)xmpp_setPresence: (XMPPPresence *)presence - (void)xmpp_setPresence: (XMPPPresence *)presence
resource: (OFString *)resource; resource: (OFString *)resource;
- (void)xmpp_removePresenceForResource: (OFString *)resource; - (void)xmpp_removePresenceForResource: (OFString *)resource;
- (void)xmpp_setLockedOnJID: (nullable XMPPJID *)JID;
@end @end
OF_ASSUME_NONNULL_END OF_ASSUME_NONNULL_END

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -57,9 +57,9 @@
connection: (XMPPConnection *)connection connection: (XMPPConnection *)connection
{ {
if (_lockedOnJID == nil) if (_lockedOnJID == nil)
[message setTo: [_rosterItem JID]]; message.to = _rosterItem.JID;
else else
[message setTo: _lockedOnJID]; message.to = _lockedOnJID;
[connection sendStanza: message]; [connection sendStanza: message];
} }
@ -81,7 +81,7 @@
[_presences setObject: presence [_presences setObject: presence
forKey: @""]; forKey: @""];
[self xmpp_setLockedOnJID: nil]; self.xmpp_lockedOnJID = nil;
} }
- (void)xmpp_removePresenceForResource: (OFString *)resource - (void)xmpp_removePresenceForResource: (OFString *)resource
@ -93,7 +93,7 @@
_presences = [[OFMutableDictionary alloc] init]; _presences = [[OFMutableDictionary alloc] init];
} }
[self xmpp_setLockedOnJID: nil]; self.xmpp_lockedOnJID = nil;
} }
- (void)xmpp_setLockedOnJID: (XMPPJID *)JID; - (void)xmpp_setLockedOnJID: (XMPPJID *)JID;

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -67,7 +67,7 @@
- (void)sendSubscribedToJID: (XMPPJID *)subscriber - (void)sendSubscribedToJID: (XMPPJID *)subscriber
{ {
XMPPPresence *presence = [XMPPPresence presenceWithType: @"subscribed"]; XMPPPresence *presence = [XMPPPresence presenceWithType: @"subscribed"];
[presence setTo: subscriber]; presence.to = subscriber;
[_connection sendStanza: presence]; [_connection sendStanza: presence];
} }
@ -75,7 +75,7 @@
{ {
XMPPPresence *presence = XMPPPresence *presence =
[XMPPPresence presenceWithType: @"unsubscribed"]; [XMPPPresence presenceWithType: @"unsubscribed"];
[presence setTo: subscriber]; presence.to = subscriber;
[_connection sendStanza: presence]; [_connection sendStanza: presence];
} }
@ -103,11 +103,10 @@
_contacts = [[OFMutableDictionary alloc] init]; _contacts = [[OFMutableDictionary alloc] init];
rosterItems = [roster rosterItems]; rosterItems = roster.rosterItems;
for (OFString *bareJID in rosterItems) { for (OFString *bareJID in rosterItems) {
XMPPContact *contact = [[[XMPPContact alloc] init] autorelease]; XMPPContact *contact = [[[XMPPContact alloc] init] autorelease];
[contact xmpp_setRosterItem: contact.rosterItem = [rosterItems objectForKey: bareJID];
[rosterItems objectForKey: bareJID]];
[_contacts setObject: contact [_contacts setObject: contact
forKey: bareJID]; forKey: bareJID];
[_delegates broadcastSelector: @selector(contactManager: [_delegates broadcastSelector: @selector(contactManager:
@ -121,11 +120,11 @@
didReceiveRosterItem: (XMPPRosterItem *)rosterItem didReceiveRosterItem: (XMPPRosterItem *)rosterItem
{ {
XMPPContact *contact; XMPPContact *contact;
OFString *bareJID = [[rosterItem JID] bareJID]; OFString *bareJID = rosterItem.JID.bareJID;
contact = [_contacts objectForKey: bareJID]; contact = [_contacts objectForKey: bareJID];
if ([[rosterItem subscription] isEqual: @"remove"]) { if ([rosterItem.subscription isEqual: @"remove"]) {
if (contact != nil) if (contact != nil)
[_delegates broadcastSelector: @selector(contactManager: [_delegates broadcastSelector: @selector(contactManager:
didRemoveContact:) didRemoveContact:)
@ -137,7 +136,7 @@
if (contact == nil) { if (contact == nil) {
contact = [[[XMPPContact alloc] init] autorelease]; contact = [[[XMPPContact alloc] init] autorelease];
[contact xmpp_setRosterItem: rosterItem]; contact.rosterItem = rosterItem;
[_contacts setObject: contact [_contacts setObject: contact
forKey: bareJID]; forKey: bareJID];
[_delegates broadcastSelector: @selector(contactManager: [_delegates broadcastSelector: @selector(contactManager:
@ -149,7 +148,7 @@
willUpdateWithRosterItem:) willUpdateWithRosterItem:)
withObject: contact withObject: contact
withObject: rosterItem]; withObject: rosterItem];
[contact xmpp_setRosterItem: rosterItem]; contact.rosterItem = rosterItem;
} }
} }
@ -157,8 +156,8 @@
didReceivePresence: (XMPPPresence *)presence didReceivePresence: (XMPPPresence *)presence
{ {
XMPPContact *contact; XMPPContact *contact;
XMPPJID *JID = [presence from]; XMPPJID *JID = presence.from;
OFString *type = [presence type]; OFString *type = presence.type;
/* Subscription request */ /* Subscription request */
if ([type isEqual: @"subscribe"]) { if ([type isEqual: @"subscribe"]) {
@ -170,14 +169,14 @@
return; return;
} }
contact = [_contacts objectForKey: [JID bareJID]]; contact = [_contacts objectForKey: JID.bareJID];
if (contact == nil) if (contact == nil)
return; return;
/* Available presence */ /* Available presence */
if ([type isEqual: @"available"]) { if ([type isEqual: @"available"]) {
[contact xmpp_setPresence: presence [contact xmpp_setPresence: presence
resource: [JID resource]]; resource: JID.resource];
[_delegates broadcastSelector: @selector(contact: [_delegates broadcastSelector: @selector(contact:
didSendPresence:) didSendPresence:)
withObject: contact withObject: contact
@ -187,7 +186,7 @@
/* Unavailable presence */ /* Unavailable presence */
if ([type isEqual: @"unavailable"]) { if ([type isEqual: @"unavailable"]) {
[contact xmpp_removePresenceForResource: [JID resource]]; [contact xmpp_removePresenceForResource: JID.resource];
[_delegates broadcastSelector: @selector(contact: [_delegates broadcastSelector: @selector(contact:
didSendPresence:) didSendPresence:)
withObject: contact withObject: contact
@ -199,13 +198,13 @@
- (void)connection: (XMPPConnection *)connection - (void)connection: (XMPPConnection *)connection
didReceiveMessage: (XMPPMessage *)message didReceiveMessage: (XMPPMessage *)message
{ {
XMPPJID *JID = [message from]; XMPPJID *JID = message.from;
XMPPContact *contact = [_contacts objectForKey: [JID bareJID]]; XMPPContact *contact = [_contacts objectForKey: JID.bareJID];
if (contact == nil) if (contact == nil)
return; return;
[contact xmpp_setLockedOnJID: JID]; contact.xmpp_lockedOnJID = JID;
[_delegates broadcastSelector: @selector(contact:didSendMessage:) [_delegates broadcastSelector: @selector(contact:didSendMessage:)
withObject: contact withObject: contact

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -108,7 +108,7 @@
- (void)addDiscoNode: (XMPPDiscoNode *)node - (void)addDiscoNode: (XMPPDiscoNode *)node
{ {
[_discoNodes setObject: node [_discoNodes setObject: node
forKey: [node node]]; forKey: node.node];
} }
- (OFString *)capsHash - (OFString *)capsHash
@ -118,19 +118,19 @@
OFData *digest; OFData *digest;
for (XMPPDiscoIdentity *identity in _identities) for (XMPPDiscoIdentity *identity in _identities)
[caps appendFormat: @"%@/%@//%@<", [identity category], [caps appendFormat: @"%@/%@//%@<",
[identity type], [identity name]]; identity.category, identity.type, identity.name];
for (OFString *feature in _features) for (OFString *feature in _features)
[caps appendFormat: @"%@<", feature]; [caps appendFormat: @"%@<", feature];
[hash updateWithBuffer: [caps UTF8String] [hash updateWithBuffer: caps.UTF8String
length: [caps UTF8StringLength]]; length: caps.UTF8StringLength];
digest = [OFData dataWithItems: [hash digest] digest = [OFData dataWithItems: hash.digest
count: [[hash class] digestSize]]; count: hash.digestSize];
return [digest stringByBase64Encoding]; return digest.stringByBase64Encoding;
} }
- (void)connection: (XMPPConnection *)connection - (void)connection: (XMPPConnection *)connection
@ -142,15 +142,14 @@
- (bool)connection: (XMPPConnection *)connection - (bool)connection: (XMPPConnection *)connection
didReceiveIQ: (XMPPIQ *)IQ didReceiveIQ: (XMPPIQ *)IQ
{ {
if (![[IQ to] isEqual: _JID]) if (![IQ.to isEqual: _JID])
return false; return false;
OFXMLElement *query = [IQ elementForName: @"query" OFXMLElement *query = [IQ elementForName: @"query"
namespace: XMPP_NS_DISCO_ITEMS]; namespace: XMPP_NS_DISCO_ITEMS];
if (query != nil) { if (query != nil) {
OFString *node = OFString *node = [query attributeForName: @"node"].stringValue;
[[query attributeForName: @"node"] stringValue];
if (node == nil) if (node == nil)
return [self xmpp_handleItemsIQ: IQ return [self xmpp_handleItemsIQ: IQ
connection: connection]; connection: connection];
@ -167,15 +166,14 @@
namespace: XMPP_NS_DISCO_INFO]; namespace: XMPP_NS_DISCO_INFO];
if (query != nil) { if (query != nil) {
OFString *node = OFString *node = [query attributeForName: @"node"].stringValue;
[[query attributeForName: @"node"] stringValue];
if (node == nil) if (node == nil)
return [self xmpp_handleInfoIQ: IQ return [self xmpp_handleInfoIQ: IQ
connection: connection]; connection: connection];
OFString *capsNode = [_capsNode stringByAppendingFormat: @"#%@", OFString *capsNode =
[self capsHash]]; [_capsNode stringByAppendingFormat: @"#%@", self.capsHash];
if ([capsNode isEqual: node]) if ([capsNode isEqual: node])
return [self xmpp_handleInfoIQ: IQ return [self xmpp_handleInfoIQ: IQ
connection: connection]; connection: connection];

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -52,9 +52,9 @@
if (category == nil || type == nil) if (category == nil || type == nil)
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
_category = [category copy]; _category = category.copy;
_name = [name copy]; _name = name.copy;
_type = [type copy]; _type = type.copy;
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -111,9 +111,9 @@
OF_HASH_INIT(hash); OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [_category hash]); OF_HASH_ADD_HASH(hash, _category.hash);
OF_HASH_ADD_HASH(hash, [_type hash]); OF_HASH_ADD_HASH(hash, _type.hash);
OF_HASH_ADD_HASH(hash, [_name hash]); OF_HASH_ADD_HASH(hash, _name.hash);
OF_HASH_FINALIZE(hash); OF_HASH_FINALIZE(hash);

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2013, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -117,7 +117,7 @@
- (void)addChildNode: (XMPPDiscoNode *)node - (void)addChildNode: (XMPPDiscoNode *)node
{ {
[_childNodes setObject: node [_childNodes setObject: node
forKey: [node node]]; forKey: node.node];
} }
- (bool)xmpp_handleItemsIQ: (XMPPIQ *)IQ - (bool)xmpp_handleItemsIQ: (XMPPIQ *)IQ
@ -143,13 +143,13 @@
namespace: XMPP_NS_DISCO_ITEMS]; namespace: XMPP_NS_DISCO_ITEMS];
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid"
stringValue: [[child JID] fullJID]]; stringValue: child.JID.fullJID];
if ([child node] != nil) if (child.node != nil)
[item addAttributeWithName: @"node" [item addAttributeWithName: @"node"
stringValue: [child node]]; stringValue: child.node];
if ([child name] != nil) if (child.name != nil)
[item addAttributeWithName: @"name" [item addAttributeWithName: @"name"
stringValue: [child name]]; stringValue: child.name];
[response addChild: item]; [response addChild: item];
} }
@ -176,12 +176,12 @@
namespace: XMPP_NS_DISCO_INFO]; namespace: XMPP_NS_DISCO_INFO];
[identityElement addAttributeWithName: @"category" [identityElement addAttributeWithName: @"category"
stringValue: [identity category]]; stringValue: identity.category];
[identityElement addAttributeWithName: @"type" [identityElement addAttributeWithName: @"type"
stringValue: [identity type]]; stringValue: identity.type];
if ([identity name] != nil) if (identity.name != nil)
[identityElement addAttributeWithName: @"name" [identityElement addAttributeWithName: @"name"
stringValue: [identity name]]; stringValue: identity.name];
[response addChild: identityElement]; [response addChild: identityElement];
} }

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2019, Jonathan Schleifer <js@heap.zone>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -44,8 +45,8 @@
/* authzid */ /* authzid */
if (_authzid != nil) if (_authzid != nil)
[message addItems: [_authzid UTF8String] [message addItems: _authzid.UTF8String
count: [_authzid UTF8StringLength]]; count: _authzid.UTF8StringLength];
[message makeImmutable]; [message makeImmutable];

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2012, 2019, Jonathan Schleifer <js@webkeks.org>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -50,8 +50,8 @@
_file = [file copy]; _file = [file copy];
@try { @try {
_data = [[[OFData dataWithContentsOfFile: file] _data = [[OFData dataWithContentsOfFile: file]
messagePackValue] retain]; .messagePackValue copy];
} @catch (id e) { } @catch (id e) {
_data = [[OFMutableDictionary alloc] init]; _data = [[OFMutableDictionary alloc] init];
} }
@ -75,7 +75,7 @@
- (void)save - (void)save
{ {
[[_data messagePackRepresentation] writeToFile: _file]; [_data.messagePackRepresentation writeToFile: _file];
} }
- (void)xmpp_setObject: (id)object - (void)xmpp_setObject: (id)object
@ -83,7 +83,7 @@
{ {
OFArray *pathComponents = [path componentsSeparatedByString: @"."]; OFArray *pathComponents = [path componentsSeparatedByString: @"."];
OFMutableDictionary *iter = _data; OFMutableDictionary *iter = _data;
size_t i = 0, components = [pathComponents count]; size_t i = 0, components = pathComponents.count;
for (OFString *component in pathComponents) { for (OFString *component in pathComponents) {
if (i++ == components - 1) if (i++ == components - 1)
@ -104,7 +104,7 @@
[iter setObject: object [iter setObject: object
forKey: [pathComponents lastObject]]; forKey: [pathComponents lastObject]];
else else
[iter removeObjectForKey: [pathComponents lastObject]]; [iter removeObjectForKey: pathComponents.lastObject];
} }
- (id)xmpp_objectForPath: (OFString *)path - (id)xmpp_objectForPath: (OFString *)path

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2011, 2019, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -56,9 +56,9 @@
- (XMPPIQ *)resultIQ - (XMPPIQ *)resultIQ
{ {
XMPPIQ *ret = [XMPPIQ IQWithType: @"result" XMPPIQ *ret = [XMPPIQ IQWithType: @"result"
ID: [self ID]]; ID: self.ID];
[ret setTo: [self from]]; ret.to = self.from;
[ret setFrom: nil]; ret.from = nil;
return ret; return ret;
} }
@ -67,7 +67,7 @@
text: (OFString *)text text: (OFString *)text
{ {
XMPPIQ *ret = [XMPPIQ IQWithType: @"error" XMPPIQ *ret = [XMPPIQ IQWithType: @"error"
ID: [self ID]]; ID: self.ID];
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
OFXMLElement *error = [OFXMLElement elementWithName: @"error" OFXMLElement *error = [OFXMLElement elementWithName: @"error"
namespace: XMPP_NS_CLIENT]; namespace: XMPP_NS_CLIENT];
@ -81,8 +81,8 @@
namespace: XMPP_NS_STANZAS namespace: XMPP_NS_STANZAS
stringValue: text]]; stringValue: text]];
[ret addChild: error]; [ret addChild: error];
[ret setTo: [self from]]; ret.to = self.from;
[ret setFrom: nil]; ret.from = nil;
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2019, Jonathan Schleifer <js@heap.zone>
* Copyright (c) 2011, 2012, 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, 2012, 2013, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -45,36 +45,39 @@
- (instancetype)initWithString: (OFString *)string - (instancetype)initWithString: (OFString *)string
{ {
size_t nodesep, resourcesep;
self = [super init]; self = [super init];
if (string == nil) { @try {
size_t nodesep, resourcesep;
if (string == nil)
@throw [OFInvalidArgumentException exception];
nodesep = [string rangeOfString: @"@"].location;
resourcesep = [string rangeOfString: @"/"].location;
if (nodesep == SIZE_MAX)
self.node = nil;
else
self.node =
[string substringWithRange: of_range(0, nodesep)];
if (resourcesep == SIZE_MAX) {
self.resource = nil;
resourcesep = string.length;
} else {
of_range_t range = of_range(resourcesep + 1,
string.length - resourcesep - 1);
self.resource = [string substringWithRange: range];
}
self.domain = [string substringWithRange:
of_range(nodesep + 1, resourcesep - nodesep - 1)];
} @catch (id e) {
[self release]; [self release];
return nil; @throw e;
} }
nodesep = [string rangeOfString: @"@"].location;
resourcesep = [string rangeOfString: @"/"].location;
if (nodesep == SIZE_MAX)
[self setNode: nil];
else
[self setNode:
[string substringWithRange: of_range(0, nodesep)]];
if (resourcesep == SIZE_MAX) {
[self setResource: nil];
resourcesep = [string length];
} else {
of_range_t range = of_range(resourcesep + 1,
[string length] - resourcesep - 1);
[self setResource: [string substringWithRange: range]];
}
[self setDomain: [string substringWithRange:
of_range(nodesep + 1, resourcesep - nodesep - 1)]];
return self; return self;
} }
@ -115,7 +118,7 @@
return; return;
} }
if (((rc = stringprep_profile([node UTF8String], &nodepart, if (((rc = stringprep_profile(node.UTF8String, &nodepart,
"Nodeprep", 0)) != STRINGPREP_OK) || (nodepart[0] == '\0') || "Nodeprep", 0)) != STRINGPREP_OK) || (nodepart[0] == '\0') ||
(strlen(nodepart) > 1023)) (strlen(nodepart) > 1023))
@throw [XMPPStringPrepFailedException @throw [XMPPStringPrepFailedException
@ -138,7 +141,7 @@
char *srv; char *srv;
Stringprep_rc rc; Stringprep_rc rc;
if (((rc = stringprep_profile([domain UTF8String], &srv, if (((rc = stringprep_profile(domain.UTF8String, &srv,
"Nameprep", 0)) != STRINGPREP_OK) || (srv[0] == '\0') || "Nameprep", 0)) != STRINGPREP_OK) || (srv[0] == '\0') ||
(strlen(srv) > 1023)) (strlen(srv) > 1023))
@throw [XMPPStringPrepFailedException @throw [XMPPStringPrepFailedException
@ -167,7 +170,7 @@
return; return;
} }
if (((rc = stringprep_profile([resource UTF8String], &res, if (((rc = stringprep_profile(resource.UTF8String, &res,
"Resourceprep", 0)) != STRINGPREP_OK) || (res[0] == '\0') || "Resourceprep", 0)) != STRINGPREP_OK) || (res[0] == '\0') ||
(strlen(res) > 1023)) (strlen(res) > 1023))
@throw [XMPPStringPrepFailedException @throw [XMPPStringPrepFailedException
@ -196,14 +199,14 @@
{ {
/* If we don't have a resource, the full JID is equal to the bare JID */ /* If we don't have a resource, the full JID is equal to the bare JID */
if (_resource == nil) if (_resource == nil)
return [self bareJID]; return self.bareJID;
if (_node != nil) if (_node != nil)
return [OFString stringWithFormat: @"%@@%@/%@", return [OFString stringWithFormat: @"%@@%@/%@",
_node, _domain, _resource]; _node, _domain, _resource];
else else
return [OFString stringWithFormat: @"%@/%@", return [OFString stringWithFormat: @"%@/%@",
_domain, _resource]; _domain, _resource];
} }
- (OFString *)description - (OFString *)description
@ -238,9 +241,9 @@
OF_HASH_INIT(hash); OF_HASH_INIT(hash);
OF_HASH_ADD_HASH(hash, [_node hash]); OF_HASH_ADD_HASH(hash, _node.hash);
OF_HASH_ADD_HASH(hash, [_domain hash]); OF_HASH_ADD_HASH(hash, _domain.hash);
OF_HASH_ADD_HASH(hash, [_resource hash]); OF_HASH_ADD_HASH(hash, _resource.hash);
OF_HASH_FINALIZE(hash); OF_HASH_FINALIZE(hash);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2019, Jonathan Schleifer <js@heap.zone>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -91,7 +91,7 @@
- (OFString *)body - (OFString *)body
{ {
return [[self elementForName: @"body" return [self elementForName: @"body"
namespace: XMPP_NS_CLIENT] stringValue]; namespace: XMPP_NS_CLIENT].stringValue;
} }
@end @end

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2012, 2019, Jonathan Schleifer <js@webkeks.org>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -57,8 +57,8 @@
- (void)removeDelegate: (id)delegate - (void)removeDelegate: (id)delegate
{ {
id *items = [_delegates items]; id const *items = _delegates.items;
size_t i, count = [_delegates count]; size_t i, count = _delegates.count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if (items[i] != delegate) if (items[i] != delegate)
@ -74,8 +74,8 @@
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
OFMutableData *currentDelegates = [[_delegates copy] autorelease]; OFMutableData *currentDelegates = [[_delegates copy] autorelease];
id *items = [currentDelegates items]; id const *items = currentDelegates.items;
size_t i, count = [currentDelegates count]; size_t i, count = currentDelegates.count;
bool handled = false; bool handled = false;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
@ -101,8 +101,8 @@
{ {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
OFMutableData *currentDelegates = [[_delegates copy] autorelease]; OFMutableData *currentDelegates = [[_delegates copy] autorelease];
id *items = [currentDelegates items]; id const *items = currentDelegates.items;
size_t i, count = [currentDelegates count]; size_t i, count = currentDelegates.count;
bool handled = false; bool handled = false;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2019, Jonathan Schleifer <js@webkeks.org>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -48,22 +49,22 @@
/* authzid */ /* authzid */
if (_authzid != nil) if (_authzid != nil)
[message addItems: [_authzid UTF8String] [message addItems: _authzid.UTF8String
count: [_authzid UTF8StringLength]]; count: _authzid.UTF8StringLength];
/* separator */ /* separator */
[message addItem: ""]; [message addItem: ""];
/* authcid */ /* authcid */
[message addItems: [_authcid UTF8String] [message addItems: _authcid.UTF8String
count: [_authcid UTF8StringLength]]; count: _authcid.UTF8StringLength];
/* separator */ /* separator */
[message addItem: ""]; [message addItem: ""];
/* passwd */ /* passwd */
[message addItems: [_password UTF8String] [message addItems: _password.UTF8String
count: [_password UTF8StringLength]]; count: _password.UTF8StringLength];
[message makeImmutable]; [message makeImmutable];

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
* Copyright (c) 2011, 2012, 2013, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, 2012, 2013, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -30,7 +30,7 @@
/* This provides us with sortable values for show values */ /* This provides us with sortable values for show values */
static int static int
show_to_int(OFString *show) showToInt(OFString *show)
{ {
if ([show isEqual: @"chat"]) if ([show isEqual: @"chat"])
return 0; return 0;
@ -106,17 +106,16 @@ show_to_int(OFString *show)
if ((subElement = [element elementForName: @"show" if ((subElement = [element elementForName: @"show"
namespace: XMPP_NS_CLIENT])) namespace: XMPP_NS_CLIENT]))
[self setShow: [subElement stringValue]]; self.show = subElement.stringValue;
if ((subElement = [element elementForName: @"status" if ((subElement = [element elementForName: @"status"
namespace: XMPP_NS_CLIENT])) namespace: XMPP_NS_CLIENT]))
[self setStatus: [subElement stringValue]]; self.status = subElement.stringValue;
if ((subElement = [element elementForName: @"priority" if ((subElement = [element elementForName: @"priority"
namespace: XMPP_NS_CLIENT])) namespace: XMPP_NS_CLIENT]))
[self setPriority: self.priority = [OFNumber
[OFNumber numberWithIntMax: numberWithIntMax: subElement.decimalValue];
[[subElement stringValue] decimalValue]]];
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -174,7 +173,7 @@ show_to_int(OFString *show)
- (void)setPriority: (OFNumber *)priority - (void)setPriority: (OFNumber *)priority
{ {
intmax_t prio = [priority intMaxValue]; intmax_t prio = priority.intMaxValue;
OFNumber *old; OFNumber *old;
if ((prio < -128) || (prio > 127)) if ((prio < -128) || (prio > 127))
@ -187,7 +186,7 @@ show_to_int(OFString *show)
[self removeChild: oldPriority]; [self removeChild: oldPriority];
OFString *priority_s = OFString *priority_s =
[OFString stringWithFormat: @"%" @PRId8, [priority int8Value]]; [OFString stringWithFormat: @"%" @PRId8, priority.int8Value];
[self addChild: [OFXMLElement elementWithName: @"priority" [self addChild: [OFXMLElement elementWithName: @"priority"
namespace: XMPP_NS_CLIENT namespace: XMPP_NS_CLIENT
stringValue: priority_s]]; stringValue: priority_s]];
@ -211,7 +210,7 @@ show_to_int(OFString *show)
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
otherPresence = (XMPPPresence *)object; otherPresence = (XMPPPresence *)object;
otherPriority = [otherPresence priority]; otherPriority = otherPresence.priority;
if (otherPriority == nil) if (otherPriority == nil)
otherPriority = [OFNumber numberWithInt8: 0]; otherPriority = [OFNumber numberWithInt8: 0];
@ -224,11 +223,11 @@ show_to_int(OFString *show)
if (priorityOrder != OF_ORDERED_SAME) if (priorityOrder != OF_ORDERED_SAME)
return priorityOrder; return priorityOrder;
otherShow = [otherPresence show]; otherShow = otherPresence.show;
if ([_show isEqual: otherShow]) if ([_show isEqual: otherShow])
return OF_ORDERED_SAME; return OF_ORDERED_SAME;
if (show_to_int(_show) < show_to_int(otherShow)) if (showToInt(_show) < showToInt(otherShow))
return OF_ORDERED_ASCENDING; return OF_ORDERED_ASCENDING;
return OF_ORDERED_DESCENDING; return OF_ORDERED_DESCENDING;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, 2016, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2016, 2019, Jonathan Schleifer <js@heap.zone>
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -66,7 +66,7 @@ OF_ASSUME_NONNULL_END
_connection = connection; _connection = connection;
[_connection addDelegate: self]; [_connection addDelegate: self];
_delegates = [[XMPPMulticastDelegate alloc] init]; _delegates = [[XMPPMulticastDelegate alloc] init];
_dataStorage = [_connection dataStorage]; _dataStorage = _connection.dataStorage;
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -86,18 +86,18 @@ OF_ASSUME_NONNULL_END
- (void)requestRoster - (void)requestRoster
{ {
XMPPIQ *iq; XMPPIQ *IQ;
OFXMLElement *query; OFXMLElement *query;
_rosterRequested = true; _rosterRequested = true;
iq = [XMPPIQ IQWithType: @"get" IQ = [XMPPIQ IQWithType: @"get"
ID: [_connection generateStanzaID]]; ID: [_connection generateStanzaID]];
query = [OFXMLElement elementWithName: @"query" query = [OFXMLElement elementWithName: @"query"
namespace: XMPP_NS_ROSTER]; namespace: XMPP_NS_ROSTER];
if ([_connection supportsRosterVersioning]) { if (_connection.supportsRosterVersioning) {
OFString *ver = OFString *ver =
[_dataStorage stringValueForPath: @"roster.ver"]; [_dataStorage stringValueForPath: @"roster.ver"];
@ -108,9 +108,9 @@ OF_ASSUME_NONNULL_END
stringValue: ver]; stringValue: ver];
} }
[iq addChild: query]; [IQ addChild: query];
[_connection sendIQ: iq [_connection sendIQ: IQ
callbackTarget: self callbackTarget: self
selector: @selector(xmpp_handleInitialRosterForConnection: selector: @selector(xmpp_handleInitialRosterForConnection:
IQ:)]; IQ:)];
@ -130,12 +130,12 @@ OF_ASSUME_NONNULL_END
if (rosterElement == nil) if (rosterElement == nil)
return false; return false;
if (![[IQ type] isEqual: @"set"]) if (![IQ.type isEqual: @"set"])
return false; return false;
// Ensure the roster push has been sent by the server // Ensure the roster push has been sent by the server
origin = [[IQ from] fullJID]; origin = IQ.from.fullJID;
if (origin != nil && ![origin isEqual: [[connection JID] bareJID]]) if (origin != nil && ![origin isEqual: connection.JID.bareJID])
return false; return false;
element = [rosterElement elementForName: @"item" element = [rosterElement elementForName: @"item"
@ -152,9 +152,9 @@ OF_ASSUME_NONNULL_END
[self xmpp_updateRosterItem: rosterItem]; [self xmpp_updateRosterItem: rosterItem];
} }
if ([_connection supportsRosterVersioning]) { if (_connection.supportsRosterVersioning) {
OFString *ver = OFString *ver =
[[rosterElement attributeForName: @"ver"] stringValue]; [rosterElement attributeForName: @"ver"].stringValue;
[_dataStorage setStringValue: ver [_dataStorage setStringValue: ver
forPath: @"roster.ver"]; forPath: @"roster.ver"];
[_dataStorage save]; [_dataStorage save];
@ -180,12 +180,12 @@ OF_ASSUME_NONNULL_END
namespace: XMPP_NS_ROSTER]; namespace: XMPP_NS_ROSTER];
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid"
stringValue: [[rosterItem JID] bareJID]]; stringValue: rosterItem.JID.bareJID];
if ([rosterItem name] != nil) if (rosterItem.name != nil)
[item addAttributeWithName: @"name" [item addAttributeWithName: @"name"
stringValue: [rosterItem name]]; stringValue: rosterItem.name];
for (OFString *group in [rosterItem groups]) for (OFString *group in rosterItem.groups)
[item addChild: [OFXMLElement elementWithName: @"group" [item addChild: [OFXMLElement elementWithName: @"group"
namespace: XMPP_NS_ROSTER namespace: XMPP_NS_ROSTER
stringValue: group]]; stringValue: group]];
@ -206,7 +206,7 @@ OF_ASSUME_NONNULL_END
namespace: XMPP_NS_ROSTER]; namespace: XMPP_NS_ROSTER];
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid"
stringValue: [[rosterItem JID] bareJID]]; stringValue: rosterItem.JID.bareJID];
[item addAttributeWithName: @"subscription" [item addAttributeWithName: @"subscription"
stringValue: @"remove"]; stringValue: @"remove"];
@ -237,42 +237,42 @@ OF_ASSUME_NONNULL_END
- (void)xmpp_updateRosterItem: (XMPPRosterItem *)rosterItem - (void)xmpp_updateRosterItem: (XMPPRosterItem *)rosterItem
{ {
if ([_connection supportsRosterVersioning]) { if (_connection.supportsRosterVersioning) {
OFMutableDictionary *items = [[[_dataStorage dictionaryForPath: OFMutableDictionary *items = [[[_dataStorage dictionaryForPath:
@"roster.items"] mutableCopy] autorelease]; @"roster.items"] mutableCopy] autorelease];
if (items == nil) if (items == nil)
items = [OFMutableDictionary dictionary]; items = [OFMutableDictionary dictionary];
if (![[rosterItem subscription] isEqual: @"remove"]) { if (![rosterItem.subscription isEqual: @"remove"]) {
OFMutableDictionary *item = [OFMutableDictionary OFMutableDictionary *item = [OFMutableDictionary
dictionaryWithKeysAndObjects: dictionaryWithKeysAndObjects:
@"JID", [[rosterItem JID] bareJID], @"JID", rosterItem.JID.bareJID,
@"subscription", [rosterItem subscription], @"subscription", rosterItem.subscription,
nil]; nil];
if ([rosterItem name] != nil) if (rosterItem.name != nil)
[item setObject: [rosterItem name] [item setObject: rosterItem.name
forKey: @"name"]; forKey: @"name"];
if ([rosterItem groups] != nil) if ([rosterItem groups] != nil)
[item setObject: [rosterItem groups] [item setObject: rosterItem.groups
forKey: @"groups"]; forKey: @"groups"];
[items setObject: item [items setObject: item
forKey: [[rosterItem JID] bareJID]]; forKey: rosterItem.JID.bareJID];
} else } else
[items removeObjectForKey: [[rosterItem JID] bareJID]]; [items removeObjectForKey: rosterItem.JID.bareJID];
[_dataStorage setDictionary: items [_dataStorage setDictionary: items
forPath: @"roster.items"]; forPath: @"roster.items"];
} }
if (![[rosterItem subscription] isEqual: @"remove"]) if (![rosterItem.subscription isEqual: @"remove"])
[_rosterItems setObject: rosterItem [_rosterItems setObject: rosterItem
forKey: [[rosterItem JID] bareJID]]; forKey: rosterItem.JID.bareJID];
else else
[_rosterItems removeObjectForKey: [[rosterItem JID] bareJID]]; [_rosterItems removeObjectForKey: rosterItem.JID.bareJID];
} }
- (XMPPRosterItem *)xmpp_rosterItemWithXMLElement: (OFXMLElement *)element - (XMPPRosterItem *)xmpp_rosterItemWithXMLElement: (OFXMLElement *)element
@ -280,13 +280,11 @@ OF_ASSUME_NONNULL_END
OFString *subscription; OFString *subscription;
OFMutableArray *groups = [OFMutableArray array]; OFMutableArray *groups = [OFMutableArray array];
XMPPRosterItem *rosterItem = [XMPPRosterItem rosterItem]; XMPPRosterItem *rosterItem = [XMPPRosterItem rosterItem];
[rosterItem setJID: [XMPPJID JIDWithString: rosterItem.JID = [XMPPJID JIDWithString:
[[element attributeForName: @"jid"] stringValue]]]; [element attributeForName: @"jid"].stringValue];
[rosterItem setName: rosterItem.name = [element attributeForName: @"name"].stringValue;
[[element attributeForName: @"name"] stringValue]];
subscription = [[element attributeForName: subscription = [element attributeForName: @"subscription"].stringValue;
@"subscription"] stringValue];
if (![subscription isEqual: @"none"] && if (![subscription isEqual: @"none"] &&
![subscription isEqual: @"to"] && ![subscription isEqual: @"to"] &&
@ -295,15 +293,15 @@ OF_ASSUME_NONNULL_END
![subscription isEqual: @"remove"]) ![subscription isEqual: @"remove"])
subscription = @"none"; subscription = @"none";
[rosterItem setSubscription: subscription]; rosterItem.subscription = subscription;
for (OFXMLElement *groupElement in for (OFXMLElement *groupElement in
[element elementsForName: @"group" [element elementsForName: @"group"
namespace: XMPP_NS_ROSTER]) namespace: XMPP_NS_ROSTER])
[groups addObject: [groupElement stringValue]]; [groups addObject: groupElement.stringValue];
if ([groups count] > 0) if (groups.count > 0)
[rosterItem setGroups: groups]; rosterItem.groups = groups;
return rosterItem; return rosterItem;
} }
@ -314,7 +312,7 @@ OF_ASSUME_NONNULL_END
OFXMLElement *rosterElement = [IQ elementForName: @"query" OFXMLElement *rosterElement = [IQ elementForName: @"query"
namespace: XMPP_NS_ROSTER]; namespace: XMPP_NS_ROSTER];
if ([connection supportsRosterVersioning]) { if (connection.supportsRosterVersioning) {
if (rosterElement == nil) { if (rosterElement == nil) {
for (OFDictionary *item in for (OFDictionary *item in
[_dataStorage dictionaryForPath: @"roster.items"]) { [_dataStorage dictionaryForPath: @"roster.items"]) {
@ -323,29 +321,28 @@ OF_ASSUME_NONNULL_END
rosterItem = [XMPPRosterItem rosterItem]; rosterItem = [XMPPRosterItem rosterItem];
JID = [XMPPJID JIDWithString: JID = [XMPPJID JIDWithString:
[item objectForKey: @"JID"]]; [item objectForKey: @"JID"]];
[rosterItem setJID: JID]; rosterItem.JID = JID;
[rosterItem setName: rosterItem.name = [item objectForKey: @"name"];
[item objectForKey: @"name"]]; rosterItem.subscription =
[rosterItem setSubscription: [item objectForKey: @"subscription"];
[item objectForKey: @"subscription"]]; rosterItem.groups =
[rosterItem setGroups: [item objectForKey: @"groups"];
[item objectForKey: @"groups"]];
[_rosterItems setObject: rosterItem [_rosterItems setObject: rosterItem
forKey: [JID bareJID]]; forKey: JID.bareJID];
} }
} else } else
[_dataStorage setDictionary: nil [_dataStorage setDictionary: nil
forPath: @"roster.items"]; forPath: @"roster.items"];
} }
for (OFXMLElement *element in [rosterElement children]) { for (OFXMLElement *element in rosterElement.children) {
void *pool = objc_autoreleasePoolPush(); void *pool = objc_autoreleasePoolPush();
XMPPRosterItem *rosterItem; XMPPRosterItem *rosterItem;
if (![[element name] isEqual: @"item"] || if (![element.name isEqual: @"item"] ||
![[element namespace] isEqual: XMPP_NS_ROSTER]) ![element.namespace isEqual: XMPP_NS_ROSTER])
continue; continue;
rosterItem = [self xmpp_rosterItemWithXMLElement: element]; rosterItem = [self xmpp_rosterItemWithXMLElement: element];
@ -355,9 +352,9 @@ OF_ASSUME_NONNULL_END
objc_autoreleasePoolPop(pool); objc_autoreleasePoolPop(pool);
} }
if ([connection supportsRosterVersioning] && rosterElement != nil) { if (connection.supportsRosterVersioning && rosterElement != nil) {
OFString *ver = OFString *ver =
[[rosterElement attributeForName: @"ver"] stringValue]; [rosterElement attributeForName: @"ver"].stringValue;
[_dataStorage setStringValue: ver [_dataStorage setStringValue: ver
forPath: @"roster.ver"]; forPath: @"roster.ver"];
[_dataStorage save]; [_dataStorage save];

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2011, 2019, Jonathan Schleifer <js@webkeks.org>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -141,7 +141,8 @@
withString: @"=3D"]; withString: @"=3D"];
[new replaceOccurrencesOfString: @"," [new replaceOccurrencesOfString: @","
withString: @"=2C"]; withString: @"=2C"];
_authzid = [new retain]; [new makeImmutable];
_authzid = [new copy];
} else } else
_authzid = nil; _authzid = nil;
@ -158,7 +159,8 @@
withString: @"=3D"]; withString: @"=3D"];
[new replaceOccurrencesOfString: @"," [new replaceOccurrencesOfString: @","
withString: @"=2C"]; withString: @"=2C"];
_authcid = [new retain]; [new makeImmutable];
_authcid = [new copy];
} else } else
_authcid = nil; _authcid = nil;
@ -193,11 +195,11 @@
_clientFirstMessageBare = [[OFString alloc] _clientFirstMessageBare = [[OFString alloc]
initWithFormat: @"n=%@,r=%@", _authcid, _cNonce]; initWithFormat: @"n=%@,r=%@", _authcid, _cNonce];
[ret addItems: [_GS2Header UTF8String] [ret addItems: _GS2Header.UTF8String
count: [_GS2Header UTF8StringLength]]; count: _GS2Header.UTF8StringLength];
[ret addItems: [_clientFirstMessageBare UTF8String] [ret addItems: _clientFirstMessageBare.UTF8String
count: [_clientFirstMessageBare UTF8StringLength]]; count: _clientFirstMessageBare.UTF8StringLength];
[ret makeImmutable]; [ret makeImmutable];
@ -239,14 +241,14 @@
ret = [OFMutableData data]; ret = [OFMutableData data];
authMessage = [OFMutableData data]; authMessage = [OFMutableData data];
OFString *challenge = [OFString stringWithUTF8String: [data items] OFString *challenge = [OFString stringWithUTF8String: data.items
length: [data count] * length: data.count *
[data itemSize]]; data.itemSize];
for (OFString *component in for (OFString *component in
[challenge componentsSeparatedByString: @","]) { [challenge componentsSeparatedByString: @","]) {
OFString *entry = [component substringWithRange: OFString *entry = [component substringWithRange:
of_range(2, [component length] - 2)]; of_range(2, component.length - 2)];
if ([component hasPrefix: @"r="]) { if ([component hasPrefix: @"r="]) {
if (![entry hasPrefix: _cNonce]) if (![entry hasPrefix: _cNonce])
@ -261,7 +263,7 @@
salt = [OFData dataWithBase64EncodedString: entry]; salt = [OFData dataWithBase64EncodedString: entry];
got |= GOT_SALT; got |= GOT_SALT;
} else if ([component hasPrefix: @"i="]) { } else if ([component hasPrefix: @"i="]) {
iterCount = [entry decimalValue]; iterCount = entry.decimalValue;
got |= GOT_ITERCOUNT; got |= GOT_ITERCOUNT;
} }
} }
@ -270,33 +272,33 @@
@throw [OFInvalidServerReplyException exception]; @throw [OFInvalidServerReplyException exception];
// Add c=<base64(GS2Header+channelBindingData)> // Add c=<base64(GS2Header+channelBindingData)>
tmpArray = [OFMutableData dataWithItems: [_GS2Header UTF8String] tmpArray = [OFMutableData dataWithItems: _GS2Header.UTF8String
count: [_GS2Header UTF8StringLength]]; count: _GS2Header.UTF8StringLength];
if (_plusAvailable && [_connection encrypted]) { if (_plusAvailable && _connection.encrypted) {
OFData *channelBinding = [((SSLSocket *)[_connection socket]) OFData *channelBinding = [((SSLSocket *)[_connection socket])
channelBindingDataWithType: @"tls-unique"]; channelBindingDataWithType: @"tls-unique"];
[tmpArray addItems: [channelBinding items] [tmpArray addItems: channelBinding.items
count: [channelBinding count]]; count: channelBinding.count];
} }
tmpString = [tmpArray stringByBase64Encoding]; tmpString = tmpArray.stringByBase64Encoding;
[ret addItems: "c=" [ret addItems: "c="
count: 2]; count: 2];
[ret addItems: [tmpString UTF8String] [ret addItems: tmpString.UTF8String
count: [tmpString UTF8StringLength]]; count: tmpString.UTF8StringLength];
// Add r=<nonce> // Add r=<nonce>
[ret addItem: ","]; [ret addItem: ","];
[ret addItems: "r=" [ret addItems: "r="
count: 2]; count: 2];
[ret addItems: [sNonce UTF8String] [ret addItems: sNonce.UTF8String
count: [sNonce UTF8StringLength]]; count: sNonce.UTF8StringLength];
/* /*
* IETF RFC 5802: * IETF RFC 5802:
* SaltedPassword := Hi(Normalize(password), salt, i) * SaltedPassword := Hi(Normalize(password), salt, i)
*/ */
tmpArray = [OFMutableData dataWithItems: [_password UTF8String] tmpArray = [OFMutableData dataWithItems: _password.UTF8String
count: [_password UTF8StringLength]]; count: _password.UTF8StringLength];
saltedPassword = [self xmpp_hiWithData: tmpArray saltedPassword = [self xmpp_hiWithData: tmpArray
salt: salt salt: salt
iterationCount: iterCount]; iterationCount: iterCount];
@ -307,14 +309,14 @@
* server-first-message + "," + * server-first-message + "," +
* client-final-message-without-proof * client-final-message-without-proof
*/ */
[authMessage addItems: [_clientFirstMessageBare UTF8String] [authMessage addItems: _clientFirstMessageBare.UTF8String
count: [_clientFirstMessageBare UTF8StringLength]]; count: _clientFirstMessageBare.UTF8StringLength];
[authMessage addItem: ","]; [authMessage addItem: ","];
[authMessage addItems: [data items] [authMessage addItems: data.items
count: [data count] * [data itemSize]]; count: data.count * data.itemSize];
[authMessage addItem: ","]; [authMessage addItem: ","];
[authMessage addItems: [ret items] [authMessage addItems: ret.items
count: [ret count]]; count: ret.count];
/* /*
* IETF RFC 5802: * IETF RFC 5802:
@ -336,8 +338,8 @@
* ClientSignature := HMAC(StoredKey, AuthMessage) * ClientSignature := HMAC(StoredKey, AuthMessage)
*/ */
clientSignature = [self clientSignature = [self
xmpp_HMACWithKey: [OFData dataWithItems: [hash digest] xmpp_HMACWithKey: [OFData dataWithItems: hash.digest
count: [_hashType digestSize]] count: hash.digestSize]
data: authMessage]; data: authMessage];
/* /*
@ -375,9 +377,9 @@
[ret addItem: ","]; [ret addItem: ","];
[ret addItems: "p=" [ret addItems: "p="
count: 2]; count: 2];
tmpString = [tmpArray stringByBase64Encoding]; tmpString = tmpArray.stringByBase64Encoding;
[ret addItems: [tmpString UTF8String] [ret addItems: tmpString.UTF8String
count: [tmpString UTF8StringLength]]; count: tmpString.UTF8StringLength];
return ret; return ret;
} }
@ -393,12 +395,12 @@
if (_authenticated) if (_authenticated)
return nil; return nil;
mess = [OFString stringWithUTF8String: [data items] mess = [OFString stringWithUTF8String: data.items
length: [data count] * [data itemSize]]; length: data.count * data.itemSize];
value = [mess substringWithRange: of_range(2, [mess length] - 2)]; value = [mess substringWithRange: of_range(2, mess.length - 2)];
if ([mess hasPrefix: @"v="]) { if ([mess hasPrefix: @"v="]) {
if (![value isEqual: [_serverSignature stringByBase64Encoding]]) if (![value isEqual: _serverSignature.stringByBase64Encoding])
@throw [XMPPAuthFailedException @throw [XMPPAuthFailedException
exceptionWithConnection: nil exceptionWithConnection: nil
reason: @"Received wrong " reason: @"Received wrong "
@ -441,22 +443,22 @@
uint8_t *kI = NULL, *kO = NULL; uint8_t *kI = NULL, *kO = NULL;
id <OFCryptoHash> hashI, hashO; id <OFCryptoHash> hashI, hashO;
if ([key itemSize] * [key count] > blockSize) { if (key.itemSize * key.count > blockSize) {
hashI = [[[_hashType alloc] init] autorelease]; hashI = [[[_hashType alloc] init] autorelease];
[hashI updateWithBuffer: [key items] [hashI updateWithBuffer: key.items
length: [key itemSize] * [key count]]; length: key.itemSize * key.count];
[k addItems: [hashI digest] [k addItems: hashI.digest
count: [_hashType digestSize]]; count: hashI.digestSize];
} else } else
[k addItems: [key items] [k addItems: key.items
count: [key itemSize] * [key count]]; count: key.itemSize * key.count];
@try { @try {
kI = [self allocMemoryWithSize: blockSize]; kI = [self allocMemoryWithSize: blockSize];
kO = [self allocMemoryWithSize: blockSize]; kO = [self allocMemoryWithSize: blockSize];
kSize = [k count]; kSize = k.count;
memcpy(kI, [k items], kSize); memcpy(kI, k.items, kSize);
memset(kI + kSize, 0, blockSize - kSize); memset(kI + kSize, 0, blockSize - kSize);
memcpy(kO, kI, blockSize); memcpy(kO, kI, blockSize);
@ -466,16 +468,16 @@
} }
hashI = [[[_hashType alloc] init] autorelease]; hashI = [[[_hashType alloc] init] autorelease];
[hashI updateWithBuffer: (char *)kI [hashI updateWithBuffer: kI
length: blockSize]; length: blockSize];
[hashI updateWithBuffer: [data items] [hashI updateWithBuffer: data.items
length: [data itemSize] * [data count]]; length: data.itemSize * data.count];
hashO = [[[_hashType alloc] init] autorelease]; hashO = [[[_hashType alloc] init] autorelease];
[hashO updateWithBuffer: (char *)kO [hashO updateWithBuffer: kO
length: blockSize]; length: blockSize];
[hashO updateWithBuffer: (char *)[hashI digest] [hashO updateWithBuffer: hashI.digest
length: [_hashType digestSize]]; length: hashI.digestSize];
} @finally { } @finally {
[self freeMemory: kI]; [self freeMemory: kI];
[self freeMemory: kO]; [self freeMemory: kO];

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, 2013, Jonathan Schleifer <js@heap.zone> * Copyright (c) 2011, 2012, 2013, 2019, Jonathan Schleifer <js@heap.zone>
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -129,15 +129,15 @@
![name isEqual: @"presence"]) ![name isEqual: @"presence"])
@throw [OFInvalidArgumentException exception]; @throw [OFInvalidArgumentException exception];
[self setDefaultNamespace: XMPP_NS_CLIENT]; self.defaultNamespace = XMPP_NS_CLIENT;
[self setPrefix: @"stream" [self setPrefix: @"stream"
forNamespace: XMPP_NS_STREAM]; forNamespace: XMPP_NS_STREAM];
if (type != nil) if (type != nil)
[self setType: type]; self.type = type;
if (ID != nil) if (ID != nil)
[self setID: ID]; self.ID = ID;
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -154,18 +154,18 @@
OFXMLAttribute *attribute; OFXMLAttribute *attribute;
if ((attribute = [element attributeForName: @"from"])) if ((attribute = [element attributeForName: @"from"]))
[self setFrom: self.from =
[XMPPJID JIDWithString: [attribute stringValue]]]; [XMPPJID JIDWithString: attribute.stringValue];
if ((attribute = [element attributeForName: @"to"])) if ((attribute = [element attributeForName: @"to"]))
[self setTo: self.to =
[XMPPJID JIDWithString: [attribute stringValue]]]; [XMPPJID JIDWithString: attribute.stringValue];
if ((attribute = [element attributeForName: @"type"])) if ((attribute = [element attributeForName: @"type"]))
[self setType: [attribute stringValue]]; self.type = attribute.stringValue;
if ((attribute = [element attributeForName: @"id"])) if ((attribute = [element attributeForName: @"id"]))
[self setID: [attribute stringValue]]; self.ID = attribute.stringValue;
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -194,7 +194,7 @@
if (from != nil) if (from != nil)
[self addAttributeWithName: @"from" [self addAttributeWithName: @"from"
stringValue: [from fullJID]]; stringValue: from.fullJID];
} }
- (void)setTo: (XMPPJID *)to - (void)setTo: (XMPPJID *)to
@ -207,7 +207,7 @@
if (to != nil) if (to != nil)
[self addAttributeWithName: @"to" [self addAttributeWithName: @"to"
stringValue: [to fullJID]]; stringValue: to.fullJID];
} }
- (void)setType: (OFString *)type - (void)setType: (OFString *)type

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
* Copyright (c) 2019, Jonathan Schleifer <js@heap.zone>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
* *
@ -56,8 +57,8 @@
- (void)connection: (XMPPConnection *)connection - (void)connection: (XMPPConnection *)connection
didReceiveElement: (OFXMLElement *)element didReceiveElement: (OFXMLElement *)element
{ {
OFString *elementName = [element name]; OFString *elementName = element.name;
OFString *elementNS = [element namespace]; OFString *elementNS = element.namespace;
if ([elementNS isEqual: XMPP_NS_SM]) { if ([elementNS isEqual: XMPP_NS_SM]) {
if ([elementName isEqual: @"enabled"]) { if ([elementName isEqual: @"enabled"]) {
@ -99,7 +100,7 @@
- (void)connection: (XMPPConnection *)connection - (void)connection: (XMPPConnection *)connection
wasBoundToJID: (XMPPJID *)JID wasBoundToJID: (XMPPJID *)JID
{ {
if ([connection supportsStreamManagement]) if (connection.supportsStreamManagement)
[connection sendStanza: [connection sendStanza:
[OFXMLElement elementWithName: @"enable" [OFXMLElement elementWithName: @"enable"
namespace: XMPP_NS_SM]]; namespace: XMPP_NS_SM]];

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2011, Jonathan Schleifer <js@webkeks.org> * Copyright (c) 2010, 2011, 2019, Jonathan Schleifer <js@webkeks.org>
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de> * Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
* *
* https://heap.zone/objxmpp/ * https://heap.zone/objxmpp/
@ -53,38 +53,39 @@ OF_APPLICATION_DELEGATE(AppDelegate)
OFArray *arguments = [OFApplication arguments]; OFArray *arguments = [OFApplication arguments];
XMPPPresence *pres = [XMPPPresence presence]; XMPPPresence *pres = [XMPPPresence presence];
[pres setShow: @"xa"]; pres.show = @"xa";
[pres setStatus: @"Bored"]; pres.status = @"Bored";
[pres setPriority: [OFNumber numberWithInt8: 20]]; pres.priority = [OFNumber numberWithInt8: 20];
[pres setTo: [XMPPJID JIDWithString: @"alice@example.com"]]; pres.to = [XMPPJID JIDWithString: @"alice@example.com"];
[pres setFrom: [XMPPJID JIDWithString: @"bob@example.org"]]; pres.from = [XMPPJID JIDWithString: @"bob@example.org"];
assert([[pres XMLString] isEqual: @"<presence to='alice@example.com' " assert([pres.XMLString isEqual: @"<presence to='alice@example.com' "
@"from='bob@example.org'><show>xa</show>" @"from='bob@example.org'><show>xa</show>"
@"<status>Bored</status><priority>20</priority>" @"<status>Bored</status><priority>20</priority>"
@"</presence>"]); @"</presence>"]);
XMPPPresence *pres2 = [XMPPPresence presence]; XMPPPresence *pres2 = [XMPPPresence presence];
[pres2 setShow: @"away"]; pres2.show = @"away";
[pres2 setStatus: @"Bored"]; pres2.status = @"Bored";
[pres2 setPriority: [OFNumber numberWithInt8: 23]]; pres2.priority = [OFNumber numberWithInt8: 23];
[pres2 setTo: [XMPPJID JIDWithString: @"alice@example.com"]]; pres2.to = [XMPPJID JIDWithString: @"alice@example.com"];
[pres2 setFrom: [XMPPJID JIDWithString: @"bob@example.org"]]; pres2.from = [XMPPJID JIDWithString: @"bob@example.org"];
assert([pres compare: pres2] == OF_ORDERED_ASCENDING); assert([pres compare: pres2] == OF_ORDERED_ASCENDING);
XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"]; XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"];
[msg setBody: @"Hello everyone"]; msg.body = @"Hello everyone";
[msg setTo: [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]]; msg.to = [XMPPJID JIDWithString: @"jdev@conference.jabber.org"];
[msg setFrom: [XMPPJID JIDWithString: @"alice@example.com"]]; msg.from = [XMPPJID JIDWithString: @"alice@example.com"];
assert([[msg XMLString] isEqual: @"<message type='chat' " assert([msg.XMLString isEqual: @"<message type='chat' "
@"to='jdev@conference.jabber.org' " @"to='jdev@conference.jabber.org' "
@"from='alice@example.com'><body>Hello everyone</body>" @"from='alice@example.com'><body>Hello everyone</body>"
@"</message>"]); @"</message>"]);
XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"128"]; XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
[iq setTo: [XMPPJID JIDWithString: @"juliet@capulet.lit"]]; ID: @"128"];
[iq setFrom: [XMPPJID JIDWithString: @"romeo@montague.lit"]]; IQ.to = [XMPPJID JIDWithString: @"juliet@capulet.lit"];
assert([[iq XMLString] isEqual: @"<iq type='set' id='128' " IQ.from = [XMPPJID JIDWithString: @"romeo@montague.lit"];
assert([IQ.XMLString isEqual: @"<iq type='set' id='128' "
@"to='juliet@capulet.lit' " @"to='juliet@capulet.lit' "
@"from='romeo@montague.lit'/>"]); @"from='romeo@montague.lit'/>"]);
@ -98,10 +99,10 @@ OF_APPLICATION_DELEGATE(AppDelegate)
[elem addAttributeWithName: @"id" [elem addAttributeWithName: @"id"
stringValue: @"42"]; stringValue: @"42"];
XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem]; XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem];
assert([[elem XMLString] isEqual: [stanza XMLString]]); assert([elem.XMLString isEqual: [stanza XMLString]]);
assert(([[OFString stringWithFormat: @"%@, %@, %@, %@", assert(([[OFString stringWithFormat: @"%@, %@, %@, %@",
[[stanza from] fullJID], [[stanza to] fullJID], [stanza type], stanza.from.fullJID, stanza.to.fullJID, stanza.type, stanza.ID]
[stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"])); isEqual: @"bob@localhost, alice@localhost, get, 42"]));
conn = [[XMPPConnection alloc] init]; conn = [[XMPPConnection alloc] init];
@ -109,22 +110,22 @@ OF_APPLICATION_DELEGATE(AppDelegate)
XMPPFileStorage *storage = XMPPFileStorage *storage =
[[XMPPFileStorage alloc] initWithFile: @"storage.binarypack"]; [[XMPPFileStorage alloc] initWithFile: @"storage.binarypack"];
[conn setDataStorage: storage]; conn.dataStorage = storage;
roster = [[XMPPRoster alloc] initWithConnection: conn]; roster = [[XMPPRoster alloc] initWithConnection: conn];
[roster addDelegate: self]; [roster addDelegate: self];
[[XMPPStreamManagement alloc] initWithConnection: conn]; [[XMPPStreamManagement alloc] initWithConnection: conn];
if ([arguments count] != 3) { if (arguments.count != 3) {
of_log(@"Invalid count of command line arguments!"); of_log(@"Invalid count of command line arguments!");
[OFApplication terminateWithStatus: 1]; [OFApplication terminateWithStatus: 1];
} }
[conn setDomain: [arguments objectAtIndex: 0]]; conn.domain = [arguments objectAtIndex: 0];
[conn setUsername: [arguments objectAtIndex: 1]]; conn.username = [arguments objectAtIndex: 1];
[conn setPassword: [arguments objectAtIndex: 2]]; conn.password = [arguments objectAtIndex: 2];
[conn setResource: @"ObjXMPP"]; conn.resource = @"ObjXMPP";
[conn asyncConnect]; [conn asyncConnect];
} }
@ -147,11 +148,11 @@ OF_APPLICATION_DELEGATE(AppDelegate)
} }
- (void)connection: (XMPPConnection *)conn_ - (void)connection: (XMPPConnection *)conn_
wasBoundToJID: (XMPPJID *)jid wasBoundToJID: (XMPPJID *)JID
{ {
of_log(@"Bound to JID: %@", [jid fullJID]); of_log(@"Bound to JID: %@", JID.fullJID);
of_log(@"Supports SM: %@", of_log(@"Supports SM: %@",
[conn_ supportsStreamManagement] ? @"true" : @"false"); conn_.supportsStreamManagement ? @"true" : @"false");
XMPPDiscoEntity *discoEntity = XMPPDiscoEntity *discoEntity =
[[XMPPDiscoEntity alloc] initWithConnection: conn]; [[XMPPDiscoEntity alloc] initWithConnection: conn];
@ -162,29 +163,29 @@ OF_APPLICATION_DELEGATE(AppDelegate)
name: @"ObjXMPP"]]; name: @"ObjXMPP"]];
XMPPDiscoNode *nodeMusic = XMPPDiscoNode *nodeMusic =
[XMPPDiscoNode discoNodeWithJID: jid [XMPPDiscoNode discoNodeWithJID: JID
node: @"music" node: @"music"
name: @"My music"]; name: @"My music"];
[discoEntity addChildNode: nodeMusic]; [discoEntity addChildNode: nodeMusic];
XMPPDiscoNode *nodeRHCP = XMPPDiscoNode *nodeRHCP =
[XMPPDiscoNode discoNodeWithJID: jid [XMPPDiscoNode discoNodeWithJID: JID
node: @"fa3b6" node: @"fa3b6"
name: @"Red Hot Chili Peppers"]; name: @"Red Hot Chili Peppers"];
[nodeMusic addChildNode: nodeRHCP]; [nodeMusic addChildNode: nodeRHCP];
XMPPDiscoNode *nodeStop = XMPPDiscoNode *nodeStop =
[XMPPDiscoNode discoNodeWithJID: jid [XMPPDiscoNode discoNodeWithJID: JID
node: @"qwe87" node: @"qwe87"
name: @"Can't Stop"]; name: @"Can't Stop"];
[nodeRHCP addChildNode: nodeStop]; [nodeRHCP addChildNode: nodeStop];
XMPPDiscoNode *nodeClueso = [XMPPDiscoNode discoNodeWithJID: jid XMPPDiscoNode *nodeClueso = [XMPPDiscoNode discoNodeWithJID: JID
node: @"ea386" node: @"ea386"
name: @"Clueso"]; name: @"Clueso"];
[nodeMusic addChildNode: nodeClueso]; [nodeMusic addChildNode: nodeClueso];
XMPPDiscoNode *nodeChicago = [XMPPDiscoNode discoNodeWithJID: jid XMPPDiscoNode *nodeChicago = [XMPPDiscoNode discoNodeWithJID: JID
node: @"qwr87" node: @"qwr87"
name: @"Chicago"]; name: @"Chicago"];
[nodeClueso addChildNode: nodeChicago]; [nodeClueso addChildNode: nodeChicago];
@ -202,20 +203,20 @@ OF_APPLICATION_DELEGATE(AppDelegate)
{ {
XMPPPresence *pres; XMPPPresence *pres;
of_log(@"Got roster: %@", [roster_ rosterItems]); of_log(@"Got roster: %@", roster_.rosterItems);
pres = [XMPPPresence presence]; pres = [XMPPPresence presence];
[pres setPriority: [OFNumber numberWithInt8: 10]]; pres.priority = [OFNumber numberWithInt8: 10];
[pres setStatus: @"ObjXMPP test is working!"]; pres.status = @"ObjXMPP test is working!";
[conn sendStanza: pres]; [conn sendStanza: pres];
#ifdef OF_HAVE_BLOCKS #ifdef OF_HAVE_BLOCKS
XMPPIQ *iq = [XMPPIQ IQWithType: @"get" XMPPIQ *IQ = [XMPPIQ IQWithType: @"get"
ID: [conn generateStanzaID]]; ID: [conn generateStanzaID]];
[iq addChild: [OFXMLElement elementWithName: @"ping" [IQ addChild: [OFXMLElement elementWithName: @"ping"
namespace: @"urn:xmpp:ping"]]; namespace: @"urn:xmpp:ping"]];
[conn sendIQ: iq [conn sendIQ: IQ
callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) { callbackBlock: ^ (XMPPConnection *c, XMPPIQ *resp) {
of_log(@"Ping response: %@", resp); of_log(@"Ping response: %@", resp);
}]; }];