Numeric escape absorbs the characters that follow it
ID |
objectivec.correctness.malformed_escape_sequence |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Literal Format |
Language |
Objective-C |
Description
Reports an octal escape of four or more digits or a hexadecimal escape of three or more digits inside a string or character literal, which means the escape has run into the text meant to follow it. A correctly terminated escape - up to three octal digits, up to two hexadecimal digits - is not reported here; the avoid-octal-escape rule covers the choice of notation, so the two rules never report the same escape. An escaped backslash and occurrences inside a comment are not reported.
Rationale
A hexadecimal escape has no digit limit at all, so "\x41f" is one character with the value 0x41f rather than an A followed by an f, and the value overflows a char. An octal escape stops after three digits, so "\1011" is A followed by a literal 1 - which is not what the four digits suggest either way. In both cases the literal holds different text than it appears to, and nothing in the source marks where the escape was supposed to end.
The following code illustrates the pattern detected by this rule:
@implementation Escapes
- (void)runOnEscapes {
// FLAGGED: Numeric escape absorbs the characters that follow it
NSString *hexRunOn = @"\x41f";
// FLAGGED: Numeric escape absorbs the characters that follow it
NSString *wideHex = @"\x0041";
// FLAGGED: Numeric escape absorbs the characters that follow it
NSString *octalRunOn = @"\1011";
// FLAGGED: Numeric escape absorbs the characters that follow it
char packed = '\07777';
NSLog(@"%@ %@ %@ %d", hexRunOn, wideHex, octalRunOn, packed);
}
@end
Remediation
Terminate the escape by splitting the literal at that point - write @"\x41" "f" rather than @"\x41f", and @"\101" "1" rather than @"\1011". Where the intent was a single character above the ASCII range, use a universal character name with its fixed width (\u041F) or write the character directly in a UTF-8 source file.