Improve URLs/emails detection in text mail parts
parent
7acfd8a2cd
commit
fcdc4c92c0
1
NEWS
1
NEWS
|
@ -11,6 +11,7 @@ Bug fixes
|
||||||
- [web] fixed scrolling in calendars list on Android
|
- [web] fixed scrolling in calendars list on Android
|
||||||
- [web] keep center list of Calendar module visible on small screens
|
- [web] keep center list of Calendar module visible on small screens
|
||||||
- [web] check for duplicate name only if address book name is changed
|
- [web] check for duplicate name only if address book name is changed
|
||||||
|
- [web] improved detection of URLs and email addresses in text mail parts
|
||||||
- [core] allow super users to modify any event (#4216)
|
- [core] allow super users to modify any event (#4216)
|
||||||
- [core] correctly handle the full cert chain in S/MIME
|
- [core] correctly handle the full cert chain in S/MIME
|
||||||
- [core] handle multidays events in freebusy data
|
- [core] handle multidays events in freebusy data
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* NSString+Utilities.h - this file is part of SOGo
|
/* NSString+Utilities.h - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2017 Inverse inc.
|
* Copyright (C) 2006-2019 Inverse inc.
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -67,8 +67,6 @@
|
||||||
|
|
||||||
- (NSString *) asQPSubjectString: (NSString *) encoding;
|
- (NSString *) asQPSubjectString: (NSString *) encoding;
|
||||||
|
|
||||||
- (NSRange) _rangeOfURLInRange: (NSRange) refRange;
|
|
||||||
|
|
||||||
/* LDAP */
|
/* LDAP */
|
||||||
- (BOOL) caseInsensitiveMatches: (NSString *) match;
|
- (BOOL) caseInsensitiveMatches: (NSString *) match;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* NSString+Utilities.m - this file is part of SOGo
|
/* NSString+Utilities.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2017 Inverse inc.
|
* Copyright (C) 2006-2019 Inverse inc.
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -35,7 +35,8 @@
|
||||||
|
|
||||||
static NSMutableCharacterSet *urlNonEndingChars = nil;
|
static NSMutableCharacterSet *urlNonEndingChars = nil;
|
||||||
static NSMutableCharacterSet *urlAfterEndingChars = nil;
|
static NSMutableCharacterSet *urlAfterEndingChars = nil;
|
||||||
static NSMutableCharacterSet *urlStartChars = nil;
|
static NSMutableCharacterSet *schemaStartChars = nil;
|
||||||
|
static NSMutableCharacterSet *emailStartChars = nil;
|
||||||
|
|
||||||
static NSString **cssEscapingStrings = NULL;
|
static NSString **cssEscapingStrings = NULL;
|
||||||
static unichar *cssEscapingCharacters = NULL;
|
static unichar *cssEscapingCharacters = NULL;
|
||||||
|
@ -101,27 +102,19 @@ static int cssEscapingCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSRange) _rangeOfURLInRange: (NSRange) refRange
|
- (NSRange) _rangeOfURLInRange: (NSRange) refRange
|
||||||
|
withPrefixChars: (NSCharacterSet *) startChars
|
||||||
{
|
{
|
||||||
int start, length;
|
int start, length;
|
||||||
NSRange workRange;
|
NSRange workRange;
|
||||||
|
|
||||||
// [urlNonEndingChars addCharactersInString: @">&=,.:;\t \r\n"];
|
// [urlNonEndingChars addCharactersInString: @">&=,.:;\t \r\n"];
|
||||||
// [urlAfterEndingChars addCharactersInString: @"()[]{}&;<\t \r\n"];
|
// [urlAfterEndingChars addCharactersInString: @"()[]{}&;<\t \r\n"];
|
||||||
if (!urlNonEndingChars)
|
|
||||||
{
|
|
||||||
urlNonEndingChars = [NSMutableCharacterSet new];
|
|
||||||
[urlNonEndingChars addCharactersInString: @"=,.:;&()\t \r\n"];
|
|
||||||
}
|
|
||||||
if (!urlAfterEndingChars)
|
|
||||||
{
|
|
||||||
urlAfterEndingChars = [NSMutableCharacterSet new];
|
|
||||||
[urlAfterEndingChars addCharactersInString: @"()[]\t \r\n"];
|
|
||||||
}
|
|
||||||
|
|
||||||
start = refRange.location;
|
start = refRange.location;
|
||||||
|
if (start > 0)
|
||||||
|
start--; // Start with the character before the refRange
|
||||||
while (start > -1
|
while (start > -1
|
||||||
&& ![urlAfterEndingChars characterIsMember:
|
&& [startChars characterIsMember:
|
||||||
[self characterAtIndex: start]])
|
[self characterAtIndex: start]])
|
||||||
start--;
|
start--;
|
||||||
start++;
|
start++;
|
||||||
|
|
||||||
|
@ -153,6 +146,7 @@ static int cssEscapingCount;
|
||||||
|
|
||||||
- (void) _handleURLs: (NSMutableString *) selfCopy
|
- (void) _handleURLs: (NSMutableString *) selfCopy
|
||||||
textToMatch: (NSString *) match
|
textToMatch: (NSString *) match
|
||||||
|
urlPrefixChars: (NSCharacterSet *) startChars
|
||||||
prefix: (NSString *) prefix
|
prefix: (NSString *) prefix
|
||||||
inRanges: (NSMutableArray *) ranges
|
inRanges: (NSMutableArray *) ranges
|
||||||
{
|
{
|
||||||
|
@ -162,51 +156,25 @@ static int cssEscapingCount;
|
||||||
NSRange *rangePtr;
|
NSRange *rangePtr;
|
||||||
NSString *urlText, *newUrlText;
|
NSString *urlText, *newUrlText;
|
||||||
unsigned int length, matchLength, offset;
|
unsigned int length, matchLength, offset;
|
||||||
int startLocation;
|
|
||||||
|
|
||||||
if (!urlStartChars)
|
|
||||||
{
|
|
||||||
urlStartChars = [NSMutableCharacterSet new];
|
|
||||||
[urlStartChars addCharactersInString: @"abcdefghijklmnopqrstuvwxyz"
|
|
||||||
@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
@"0123456789:@"];
|
|
||||||
}
|
|
||||||
|
|
||||||
newRanges = [NSMutableArray array];
|
newRanges = [NSMutableArray array];
|
||||||
matchLength = [match length];
|
matchLength = [match length];
|
||||||
rest.location = -1;
|
|
||||||
|
|
||||||
matchRange = [selfCopy rangeOfString: match];
|
matchRange = [selfCopy rangeOfString: match];
|
||||||
while (matchRange.location != NSNotFound)
|
while (matchRange.location != NSNotFound)
|
||||||
{
|
{
|
||||||
startLocation = matchRange.location;
|
currentUrlRange = [selfCopy _rangeOfURLInRange: matchRange
|
||||||
while (startLocation > rest.location
|
withPrefixChars: startChars];
|
||||||
&& [urlStartChars characterIsMember:
|
if (![ranges hasRangeIntersection: currentUrlRange])
|
||||||
[selfCopy characterAtIndex: startLocation]])
|
if (currentUrlRange.length > matchLength)
|
||||||
startLocation--;
|
[newRanges addNonNSObject: ¤tUrlRange
|
||||||
matchRange.location = startLocation + 1;
|
withSize: sizeof (NSRange)
|
||||||
|
copy: YES];
|
||||||
// We avoid going out of bounds if the mail content actually finishes
|
rest.location = NSMaxRange (currentUrlRange);
|
||||||
// with the @ (or something else) character
|
length = [selfCopy length];
|
||||||
if (matchRange.location < [selfCopy length])
|
rest.length = length - rest.location;
|
||||||
{
|
matchRange = [selfCopy rangeOfString: match
|
||||||
currentUrlRange = [selfCopy _rangeOfURLInRange: matchRange];
|
options: 0 range: rest];
|
||||||
if (![ranges hasRangeIntersection: currentUrlRange])
|
|
||||||
if (currentUrlRange.length > matchLength)
|
|
||||||
[newRanges addNonNSObject: ¤tUrlRange
|
|
||||||
withSize: sizeof (NSRange)
|
|
||||||
copy: YES];
|
|
||||||
|
|
||||||
rest.location = NSMaxRange (currentUrlRange);
|
|
||||||
length = [selfCopy length];
|
|
||||||
rest.length = length - rest.location;
|
|
||||||
matchRange = [selfCopy rangeOfString: match
|
|
||||||
options: 0 range: rest];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
matchRange.location = NSNotFound;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the substitutions, keep track of the new offset
|
// Make the substitutions, keep track of the new offset
|
||||||
|
@ -237,14 +205,41 @@ static int cssEscapingCount;
|
||||||
NSMutableString *selfCopy;
|
NSMutableString *selfCopy;
|
||||||
NSMutableArray *ranges;
|
NSMutableArray *ranges;
|
||||||
|
|
||||||
|
if (!urlNonEndingChars)
|
||||||
|
{
|
||||||
|
urlNonEndingChars = [NSMutableCharacterSet new];
|
||||||
|
[urlNonEndingChars addCharactersInString: @"=,.:;&()\t \r\n"];
|
||||||
|
}
|
||||||
|
if (!urlAfterEndingChars)
|
||||||
|
{
|
||||||
|
urlAfterEndingChars = [NSMutableCharacterSet new];
|
||||||
|
[urlAfterEndingChars addCharactersInString: @"()[]\t \r\n"];
|
||||||
|
}
|
||||||
|
if (!schemaStartChars)
|
||||||
|
{
|
||||||
|
schemaStartChars = [NSMutableCharacterSet new];
|
||||||
|
[schemaStartChars addCharactersInString: @"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"];
|
||||||
|
}
|
||||||
|
if (!emailStartChars)
|
||||||
|
{
|
||||||
|
emailStartChars = [NSMutableCharacterSet new];
|
||||||
|
[emailStartChars addCharactersInString: @"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
@"01234567890"
|
||||||
|
@"!#$%&'*+-/=?^`{|}~."];
|
||||||
|
}
|
||||||
|
|
||||||
ranges = [NSMutableArray array];
|
ranges = [NSMutableArray array];
|
||||||
selfCopy = [NSMutableString stringWithString: self];
|
selfCopy = [NSMutableString stringWithString: self];
|
||||||
[self _handleURLs: selfCopy
|
[self _handleURLs: selfCopy
|
||||||
textToMatch: @"://"
|
textToMatch: @"://"
|
||||||
|
urlPrefixChars: schemaStartChars
|
||||||
prefix: @""
|
prefix: @""
|
||||||
inRanges: ranges];
|
inRanges: ranges];
|
||||||
[self _handleURLs: selfCopy
|
[self _handleURLs: selfCopy
|
||||||
textToMatch: @"@"
|
textToMatch: @"@"
|
||||||
|
urlPrefixChars: emailStartChars
|
||||||
prefix: @"mailto:"
|
prefix: @"mailto:"
|
||||||
inRanges: ranges];
|
inRanges: ranges];
|
||||||
[ranges freeNonNSObjects];
|
[ranges freeNonNSObjects];
|
||||||
|
|
Loading…
Reference in New Issue