Skip to content

Commit

Permalink
Improve URLs/emails detection in text mail parts
Browse files Browse the repository at this point in the history
  • Loading branch information
cgx committed Mar 21, 2019
1 parent 7acfd8a commit fcdc4c9
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 56 deletions.
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -11,6 +11,7 @@ Bug fixes
- [web] fixed scrolling in calendars list on Android
- [web] keep center list of Calendar module visible on small screens
- [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] correctly handle the full cert chain in S/MIME
- [core] handle multidays events in freebusy data
Expand Down
4 changes: 1 addition & 3 deletions SoObjects/SOGo/NSString+Utilities.h
@@ -1,6 +1,6 @@
/* 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
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -67,8 +67,6 @@

- (NSString *) asQPSubjectString: (NSString *) encoding;

- (NSRange) _rangeOfURLInRange: (NSRange) refRange;

/* LDAP */
- (BOOL) caseInsensitiveMatches: (NSString *) match;

Expand Down
101 changes: 48 additions & 53 deletions SoObjects/SOGo/NSString+Utilities.m
@@ -1,6 +1,6 @@
/* 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
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -35,7 +35,8 @@

static NSMutableCharacterSet *urlNonEndingChars = nil;
static NSMutableCharacterSet *urlAfterEndingChars = nil;
static NSMutableCharacterSet *urlStartChars = nil;
static NSMutableCharacterSet *schemaStartChars = nil;
static NSMutableCharacterSet *emailStartChars = nil;

static NSString **cssEscapingStrings = NULL;
static unichar *cssEscapingCharacters = NULL;
Expand Down Expand Up @@ -101,27 +102,19 @@ - (NSString *) urlWithoutParameters;
}

- (NSRange) _rangeOfURLInRange: (NSRange) refRange
withPrefixChars: (NSCharacterSet *) startChars
{
int start, length;
NSRange workRange;

// [urlNonEndingChars 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;
if (start > 0)
start--; // Start with the character before the refRange
while (start > -1
&& ![urlAfterEndingChars characterIsMember:
[self characterAtIndex: start]])
&& [startChars characterIsMember:
[self characterAtIndex: start]])
start--;
start++;

Expand Down Expand Up @@ -153,6 +146,7 @@ - (NSRange) _rangeOfURLInRange: (NSRange) refRange

- (void) _handleURLs: (NSMutableString *) selfCopy
textToMatch: (NSString *) match
urlPrefixChars: (NSCharacterSet *) startChars
prefix: (NSString *) prefix
inRanges: (NSMutableArray *) ranges
{
Expand All @@ -162,51 +156,25 @@ - (void) _handleURLs: (NSMutableString *) selfCopy
NSRange *rangePtr;
NSString *urlText, *newUrlText;
unsigned int length, matchLength, offset;
int startLocation;

if (!urlStartChars)
{
urlStartChars = [NSMutableCharacterSet new];
[urlStartChars addCharactersInString: @"abcdefghijklmnopqrstuvwxyz"
@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@"0123456789:@"];
}

newRanges = [NSMutableArray array];
matchLength = [match length];
rest.location = -1;

matchRange = [selfCopy rangeOfString: match];
while (matchRange.location != NSNotFound)
{
startLocation = matchRange.location;
while (startLocation > rest.location
&& [urlStartChars characterIsMember:
[selfCopy characterAtIndex: startLocation]])
startLocation--;
matchRange.location = startLocation + 1;

// We avoid going out of bounds if the mail content actually finishes
// with the @ (or something else) character
if (matchRange.location < [selfCopy length])
{
currentUrlRange = [selfCopy _rangeOfURLInRange: matchRange];
if (![ranges hasRangeIntersection: currentUrlRange])
if (currentUrlRange.length > matchLength)
[newRanges addNonNSObject: &currentUrlRange
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;
}
currentUrlRange = [selfCopy _rangeOfURLInRange: matchRange
withPrefixChars: startChars];
if (![ranges hasRangeIntersection: currentUrlRange])
if (currentUrlRange.length > matchLength)
[newRanges addNonNSObject: &currentUrlRange
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];
}

// Make the substitutions, keep track of the new offset
Expand Down Expand Up @@ -237,14 +205,41 @@ - (NSString *) stringByDetectingURLs
NSMutableString *selfCopy;
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];
selfCopy = [NSMutableString stringWithString: self];
[self _handleURLs: selfCopy
textToMatch: @"://"
urlPrefixChars: schemaStartChars
prefix: @""
inRanges: ranges];
[self _handleURLs: selfCopy
textToMatch: @"@"
urlPrefixChars: emailStartChars
prefix: @"mailto:"
inRanges: ranges];
[ranges freeNonNSObjects];
Expand Down

0 comments on commit fcdc4c9

Please sign in to comment.