Fix bug 315759: crash when accessing Brother printer via Bonjour. Use the new Tiger -TXTRecordData stuff if we can, and protect against null -protocolSpecificInformations.

This commit is contained in:
smfr%smfr.org 2005-12-07 05:53:41 +00:00
parent f164e052fc
commit b5e2e01de8

View File

@ -50,6 +50,19 @@
#import "CHBrowserService.h" #import "CHBrowserService.h"
#import "NetworkServices.h" #import "NetworkServices.h"
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
@interface NSNetService(PreTigerUtils)
+ (NSDictionary *)dictionaryFromTXTRecordData:(NSData *)txtData;
- (BOOL)setTXTRecordData:(NSData *)recordData;
- (NSData *)TXTRecordData;
@end
#endif
@class NSNetServiceBrowser; @class NSNetServiceBrowser;
// client notifications // client notifications
@ -260,12 +273,12 @@ static inline u_int ns_get16(u_char* buffer)
int anslen = res_query([name UTF8String], C_IN, /* T_SRV */ 33, buffer, sizeof(buffer)); int anslen = res_query([name UTF8String], C_IN, /* T_SRV */ 33, buffer, sizeof(buffer));
if (anslen > 12) if (anslen > 12)
{ {
u_int dnsid = ns_get16(buffer); // u_int dnsid = ns_get16(buffer);
u_int flags = ns_get16(buffer + 2); // u_int flags = ns_get16(buffer + 2);
u_int numQuestions = ns_get16(buffer + 4); u_int numQuestions = ns_get16(buffer + 4);
u_int numAnswers = ns_get16(buffer + 6); u_int numAnswers = ns_get16(buffer + 6);
u_int numAuthorities = ns_get16(buffer + 8); // u_int numAuthorities = ns_get16(buffer + 8);
u_int numAdditionals = ns_get16(buffer + 10); // u_int numAdditionals = ns_get16(buffer + 10);
u_int rrtype, rrclass, rdlen; u_int rrtype, rrclass, rdlen;
u_char *end = buffer + anslen; u_char *end = buffer + anslen;
u_char *ptr = buffer + 12; u_char *ptr = buffer + 12;
@ -309,37 +322,63 @@ static inline u_int ns_get16(u_char* buffer)
promptPassword = YES; promptPassword = YES;
} }
NSString* serviceTextRecord = [netService protocolSpecificInformation]; NSString* path = @"";
// The text record can contain a series of name/value pairs separated by '\1'. // use the Tiger goodness if we can
// We need to search in there for a "path=" (case insensitive). if ([netService respondsToSelector:@selector(TXTRecordData)])
const char* serviceText = [serviceTextRecord cString];
const char* textPtr = serviceText;
const char* textEnd = textPtr + strlen(textPtr);
char pathBuffer[1024 + 1];
pathBuffer[0] = '\0';
BOOL chunkStart = YES;
while (textPtr < textEnd)
{ {
if (chunkStart && strncasecmp(textPtr, "path=", 5) == 0) NSDictionary* TXTRecordDict = [NSNetService dictionaryFromTXTRecordData:[netService TXTRecordData]];
NSData* pathData = [TXTRecordDict objectForKey:@"path"];
if (pathData)
{ {
const char* pathStart = textPtr; unsigned int dataLen = [pathData length];
char* pathBuff = (char*)calloc(dataLen + 1, 1);
// find the end [pathData getBytes:pathBuff length:dataLen];
while (*textPtr && (*textPtr != '\1')) pathBuff[dataLen] = '\0';
textPtr ++;
int length = textPtr - pathStart; path = [NSString stringWithUTF8String:pathBuff];
if (length > 1024)
length = 1024; free(pathBuff);
strncpy(pathBuffer, pathStart, length);
pathBuffer[length] = '\0';
break;
} }
}
else
{
NSString* serviceTextRecord = [netService protocolSpecificInformation];
if (serviceTextRecord)
{
// The text record can contain a series of name/value pairs separated by '\1'.
// We need to search in there for a "path=" (case insensitive).
const char* serviceText = [serviceTextRecord cString];
const char* textPtr = serviceText;
const char* textEnd = textPtr + strlen(textPtr);
chunkStart = (*textPtr == '\1'); char pathBuffer[1024 + 1];
textPtr ++; pathBuffer[0] = '\0';
BOOL chunkStart = YES;
while (textPtr < textEnd)
{
if (chunkStart && strncasecmp(textPtr, "path=", 5) == 0)
{
const char* pathStart = textPtr;
// find the end
while (*textPtr && (*textPtr != '\1'))
textPtr ++;
int length = textPtr - pathStart;
if (length > 1024)
length = 1024;
strncpy(pathBuffer, pathStart, length);
pathBuffer[length] = '\0';
break;
}
chunkStart = (*textPtr == '\1');
textPtr ++;
}
path = [NSString stringWithUTF8String:pathBuffer];
}
} }
NSString* urlString = nil; NSString* urlString = nil;
@ -359,10 +398,10 @@ static inline u_int ns_get16(u_char* buffer)
if (!confirmed) if (!confirmed)
return; // fix return; // fix
urlString = [NSString stringWithFormat:@"%s//%@@%s:%u%s", protocol, userName, escapedTarget, port, pathBuffer]; urlString = [NSString stringWithFormat:@"%s//%@@%s:%u%@", protocol, userName, escapedTarget, port, path];
} }
else else
urlString = [NSString stringWithFormat:@"%s//%s:%u%s", protocol, escapedTarget, port, pathBuffer]; urlString = [NSString stringWithFormat:@"%s//%s:%u%@", protocol, escapedTarget, port, path];
[self notifyClientsOfServiceResolution:netService withURL:urlString]; [self notifyClientsOfServiceResolution:netService withURL:urlString];
return; return;