mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-29 16:01:38 +00:00
header line folding fix
This commit is contained in:
parent
911c5cdd66
commit
06019034b0
3 changed files with 101 additions and 23 deletions
|
@ -3808,7 +3808,7 @@ static char* _charsToEncode = "()<>@,;:_\"/[]?.=";
|
|||
|
||||
static NSUInteger
|
||||
quotableLength(const uint8_t *ptr, NSUInteger size, NSUInteger max,
|
||||
NSUInteger *quotedLength)
|
||||
NSUInteger *quotedLength, BOOL utf8)
|
||||
{
|
||||
NSUInteger encoded;
|
||||
NSUInteger index;
|
||||
|
@ -3816,17 +3816,45 @@ quotableLength(const uint8_t *ptr, NSUInteger size, NSUInteger max,
|
|||
for (encoded = index = 0; index < size; index++)
|
||||
{
|
||||
uint8_t c = ptr[index];
|
||||
int add = 1;
|
||||
|
||||
if (c < 32 || c >= 127 || strchr(_charsToEncode, c))
|
||||
{
|
||||
add += 2;
|
||||
if (encoded + 3 > max)
|
||||
{
|
||||
break;
|
||||
}
|
||||
encoded += 3;
|
||||
}
|
||||
if (encoded + add > max)
|
||||
else
|
||||
{
|
||||
break;
|
||||
if (encoded >= max)
|
||||
{
|
||||
break;
|
||||
}
|
||||
encoded++;
|
||||
}
|
||||
}
|
||||
|
||||
if (YES == utf8 && index < size)
|
||||
{
|
||||
uint8_t c = ptr[index];
|
||||
|
||||
/* We are breaking up a utf-8 string, so we must make sure
|
||||
* we don't break inside a character.
|
||||
*/
|
||||
if ((c & 0xc0) == 0x80)
|
||||
{
|
||||
/* The next byte is a continuation byte, so we must be
|
||||
* inside a utf-8 codepoint and need to step back out
|
||||
* of it.
|
||||
*/
|
||||
do
|
||||
{
|
||||
encoded -= 3;
|
||||
c = ptr[--index];
|
||||
}
|
||||
while ((c & 0xc0) == 0x80);
|
||||
}
|
||||
encoded += add;
|
||||
}
|
||||
*quotedLength = encoded;
|
||||
return index;
|
||||
|
@ -4062,8 +4090,13 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
NSString *cset = selectCharacterSet(str, &d);
|
||||
const uint8_t *ptr = (const uint8_t*)[d bytes];
|
||||
NSUInteger len = [d length];
|
||||
BOOL utf8 = NO;
|
||||
|
||||
if ([cset isEqualToString: @"us-ascii"])
|
||||
if ([cset isEqualToString: @"utf-8"])
|
||||
{
|
||||
utf8 = YES;
|
||||
}
|
||||
else if ([cset isEqualToString: @"us-ascii"])
|
||||
{
|
||||
if (0 == fold)
|
||||
{
|
||||
|
@ -4152,7 +4185,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
uint8_t *buffer;
|
||||
NSUInteger existingLength;
|
||||
NSUInteger quotedLength;
|
||||
NSUInteger charLength;
|
||||
NSUInteger byteLength;
|
||||
uint8_t style = 'Q';
|
||||
|
||||
/* Calculate the number of encoded characters we can
|
||||
|
@ -4171,23 +4204,34 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
offset = 1;
|
||||
}
|
||||
|
||||
charLength = quotableLength(ptr + pos, len - pos,
|
||||
fold - offset - overhead, "edLength);
|
||||
if (quotedLength > (charLength * 4) / 3)
|
||||
byteLength = quotableLength(ptr + pos, len - pos,
|
||||
fold - offset - overhead, "edLength, utf8);
|
||||
if (quotedLength > (byteLength * 4) / 3)
|
||||
{
|
||||
/* Using base64 is more compact than using quoted
|
||||
* text, so lets do that.
|
||||
*/
|
||||
style = 'B';
|
||||
charLength = ((fold - offset - overhead) / 4) * 3;
|
||||
if (charLength >= len - pos)
|
||||
byteLength = ((fold - offset - overhead) / 4) * 3;
|
||||
if (byteLength >= len - pos)
|
||||
{
|
||||
/* If we have less text than we can fit,
|
||||
* just encode all of it.
|
||||
*/
|
||||
charLength = len - pos;
|
||||
byteLength = len - pos;
|
||||
}
|
||||
quotedLength = 4 * ((charLength + 2) / 3);
|
||||
else if (YES == utf8
|
||||
&& (ptr[pos + byteLength] % 0xc0) == 0x80)
|
||||
{
|
||||
/* The byte after the end of the data we propose
|
||||
* to encode is a utf8 continuation byte
|
||||
* so step back to the character boundary.
|
||||
*/
|
||||
do {
|
||||
byteLength--;
|
||||
} while ((ptr[pos + byteLength] % 0xc0) == 0x80);
|
||||
}
|
||||
quotedLength = 4 * ((byteLength + 2) / 3);
|
||||
}
|
||||
|
||||
/* make sure we have enough space in the output buffer.
|
||||
|
@ -4207,21 +4251,31 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
*buffer++ = '?';
|
||||
if ('Q' == style)
|
||||
{
|
||||
quotedWord(ptr + pos, charLength, buffer);
|
||||
quotedWord(ptr + pos, byteLength, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSPrivateEncodeBase64(ptr + pos, charLength, buffer);
|
||||
GSPrivateEncodeBase64(ptr + pos, byteLength, buffer);
|
||||
}
|
||||
buffer[quotedLength] = '?';
|
||||
buffer[quotedLength + 1] = '=';
|
||||
offset += quotedLength + overhead;
|
||||
pos += charLength;
|
||||
pos += byteLength;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
/* For testing
|
||||
+ (NSUInteger) appendString: (NSString*)str
|
||||
to: (NSMutableData*)m
|
||||
at: (NSUInteger)offset
|
||||
fold: (NSUInteger)fold
|
||||
ok: (BOOL*)ok
|
||||
{
|
||||
return appendString(m, offset, fold, str, ok);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the full text of the header, built from its component parts,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue