PrintfFormatString.cpp revision d02deebce5f1b283101e035a7f5d5bab0d2068ec
1//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Handling of format string in printf and friends. The structure of format 11// strings for fprintf() are described in C99 7.19.6.1. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/Analysis/Analyses/FormatString.h" 16#include "FormatStringParsing.h" 17 18using clang::analyze_format_string::ArgTypeResult; 19using clang::analyze_format_string::FormatStringHandler; 20using clang::analyze_format_string::LengthModifier; 21using clang::analyze_format_string::OptionalAmount; 22using clang::analyze_format_string::ConversionSpecifier; 23using clang::analyze_printf::PrintfSpecifier; 24 25using namespace clang; 26 27typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 28 PrintfSpecifierResult; 29 30//===----------------------------------------------------------------------===// 31// Methods for parsing format strings. 32//===----------------------------------------------------------------------===// 33 34using analyze_format_string::ParseNonPositionAmount; 35 36static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 37 const char *Start, const char *&Beg, const char *E, 38 unsigned *argIndex) { 39 if (argIndex) { 40 FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 41 } else { 42 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 43 analyze_format_string::PrecisionPos); 44 if (Amt.isInvalid()) 45 return true; 46 FS.setPrecision(Amt); 47 } 48 return false; 49} 50 51static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 52 const char *&Beg, 53 const char *E, 54 unsigned &argIndex, 55 const LangOptions &LO) { 56 57 using namespace clang::analyze_format_string; 58 using namespace clang::analyze_printf; 59 60 const char *I = Beg; 61 const char *Start = 0; 62 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 63 64 // Look for a '%' character that indicates the start of a format specifier. 65 for ( ; I != E ; ++I) { 66 char c = *I; 67 if (c == '\0') { 68 // Detect spurious null characters, which are likely errors. 69 H.HandleNullChar(I); 70 return true; 71 } 72 if (c == '%') { 73 Start = I++; // Record the start of the format specifier. 74 break; 75 } 76 } 77 78 // No format specifier found? 79 if (!Start) 80 return false; 81 82 if (I == E) { 83 // No more characters left? 84 H.HandleIncompleteSpecifier(Start, E - Start); 85 return true; 86 } 87 88 PrintfSpecifier FS; 89 if (ParseArgPosition(H, FS, Start, I, E)) 90 return true; 91 92 if (I == E) { 93 // No more characters left? 94 H.HandleIncompleteSpecifier(Start, E - Start); 95 return true; 96 } 97 98 // Look for flags (if any). 99 bool hasMore = true; 100 for ( ; I != E; ++I) { 101 switch (*I) { 102 default: hasMore = false; break; 103 case '\'': 104 // FIXME: POSIX specific. Always accept? 105 FS.setHasThousandsGrouping(I); 106 break; 107 case '-': FS.setIsLeftJustified(I); break; 108 case '+': FS.setHasPlusPrefix(I); break; 109 case ' ': FS.setHasSpacePrefix(I); break; 110 case '#': FS.setHasAlternativeForm(I); break; 111 case '0': FS.setHasLeadingZeros(I); break; 112 } 113 if (!hasMore) 114 break; 115 } 116 117 if (I == E) { 118 // No more characters left? 119 H.HandleIncompleteSpecifier(Start, E - Start); 120 return true; 121 } 122 123 // Look for the field width (if any). 124 if (ParseFieldWidth(H, FS, Start, I, E, 125 FS.usesPositionalArg() ? 0 : &argIndex)) 126 return true; 127 128 if (I == E) { 129 // No more characters left? 130 H.HandleIncompleteSpecifier(Start, E - Start); 131 return true; 132 } 133 134 // Look for the precision (if any). 135 if (*I == '.') { 136 ++I; 137 if (I == E) { 138 H.HandleIncompleteSpecifier(Start, E - Start); 139 return true; 140 } 141 142 if (ParsePrecision(H, FS, Start, I, E, 143 FS.usesPositionalArg() ? 0 : &argIndex)) 144 return true; 145 146 if (I == E) { 147 // No more characters left? 148 H.HandleIncompleteSpecifier(Start, E - Start); 149 return true; 150 } 151 } 152 153 // Look for the length modifier. 154 if (ParseLengthModifier(FS, I, E, LO) && I == E) { 155 // No more characters left? 156 H.HandleIncompleteSpecifier(Start, E - Start); 157 return true; 158 } 159 160 if (*I == '\0') { 161 // Detect spurious null characters, which are likely errors. 162 H.HandleNullChar(I); 163 return true; 164 } 165 166 // Finally, look for the conversion specifier. 167 const char *conversionPosition = I++; 168 ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 169 switch (*conversionPosition) { 170 default: 171 break; 172 // C99: 7.19.6.1 (section 8). 173 case '%': k = ConversionSpecifier::PercentArg; break; 174 case 'A': k = ConversionSpecifier::AArg; break; 175 case 'E': k = ConversionSpecifier::EArg; break; 176 case 'F': k = ConversionSpecifier::FArg; break; 177 case 'G': k = ConversionSpecifier::GArg; break; 178 case 'X': k = ConversionSpecifier::XArg; break; 179 case 'a': k = ConversionSpecifier::aArg; break; 180 case 'c': k = ConversionSpecifier::cArg; break; 181 case 'd': k = ConversionSpecifier::dArg; break; 182 case 'e': k = ConversionSpecifier::eArg; break; 183 case 'f': k = ConversionSpecifier::fArg; break; 184 case 'g': k = ConversionSpecifier::gArg; break; 185 case 'i': k = ConversionSpecifier::iArg; break; 186 case 'n': k = ConversionSpecifier::nArg; break; 187 case 'o': k = ConversionSpecifier::oArg; break; 188 case 'p': k = ConversionSpecifier::pArg; break; 189 case 's': k = ConversionSpecifier::sArg; break; 190 case 'u': k = ConversionSpecifier::uArg; break; 191 case 'x': k = ConversionSpecifier::xArg; break; 192 // POSIX specific. 193 case 'C': k = ConversionSpecifier::CArg; break; 194 case 'S': k = ConversionSpecifier::SArg; break; 195 // Objective-C. 196 case '@': k = ConversionSpecifier::ObjCObjArg; break; 197 // Glibc specific. 198 case 'm': k = ConversionSpecifier::PrintErrno; break; 199 } 200 PrintfConversionSpecifier CS(conversionPosition, k); 201 FS.setConversionSpecifier(CS); 202 if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 203 FS.setArgIndex(argIndex++); 204 205 if (k == ConversionSpecifier::InvalidSpecifier) { 206 // Assume the conversion takes one argument. 207 return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 208 } 209 return PrintfSpecifierResult(Start, FS); 210} 211 212bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 213 const char *I, 214 const char *E, 215 const LangOptions &LO) { 216 217 unsigned argIndex = 0; 218 219 // Keep looking for a format specifier until we have exhausted the string. 220 while (I != E) { 221 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 222 LO); 223 // Did a fail-stop error of any kind occur when parsing the specifier? 224 // If so, don't do any more processing. 225 if (FSR.shouldStop()) 226 return true;; 227 // Did we exhaust the string or encounter an error that 228 // we can recover from? 229 if (!FSR.hasValue()) 230 continue; 231 // We have a format specifier. Pass it to the callback. 232 if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 233 I - FSR.getStart())) 234 return true; 235 } 236 assert(I == E && "Format string not exhausted"); 237 return false; 238} 239 240//===----------------------------------------------------------------------===// 241// Methods on PrintfSpecifier. 242//===----------------------------------------------------------------------===// 243 244ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const { 245 const PrintfConversionSpecifier &CS = getConversionSpecifier(); 246 247 if (!CS.consumesDataArgument()) 248 return ArgTypeResult::Invalid(); 249 250 if (CS.getKind() == ConversionSpecifier::cArg) 251 switch (LM.getKind()) { 252 case LengthModifier::None: return Ctx.IntTy; 253 case LengthModifier::AsLong: 254 return ArgTypeResult(ArgTypeResult::WIntTy, "wint_t"); 255 default: 256 return ArgTypeResult::Invalid(); 257 } 258 259 if (CS.isIntArg()) 260 switch (LM.getKind()) { 261 case LengthModifier::AsLongDouble: 262 return ArgTypeResult::Invalid(); 263 case LengthModifier::None: return Ctx.IntTy; 264 case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy; 265 case LengthModifier::AsShort: return Ctx.ShortTy; 266 case LengthModifier::AsLong: return Ctx.LongTy; 267 case LengthModifier::AsLongLong: return Ctx.LongLongTy; 268 case LengthModifier::AsIntMax: 269 return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t"); 270 case LengthModifier::AsSizeT: 271 // FIXME: How to get the corresponding signed version of size_t? 272 return ArgTypeResult(); 273 case LengthModifier::AsPtrDiff: 274 return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t"); 275 case LengthModifier::AsAllocate: 276 return ArgTypeResult::Invalid(); 277 } 278 279 if (CS.isUIntArg()) 280 switch (LM.getKind()) { 281 case LengthModifier::AsLongDouble: 282 return ArgTypeResult::Invalid(); 283 case LengthModifier::None: return Ctx.UnsignedIntTy; 284 case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 285 case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 286 case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 287 case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy; 288 case LengthModifier::AsIntMax: 289 return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t"); 290 case LengthModifier::AsSizeT: 291 return ArgTypeResult(Ctx.getSizeType(), "size_t"); 292 case LengthModifier::AsPtrDiff: 293 // FIXME: How to get the corresponding unsigned 294 // version of ptrdiff_t? 295 return ArgTypeResult(); 296 case LengthModifier::AsAllocate: 297 return ArgTypeResult::Invalid(); 298 } 299 300 if (CS.isDoubleArg()) { 301 if (LM.getKind() == LengthModifier::AsLongDouble) 302 return Ctx.LongDoubleTy; 303 return Ctx.DoubleTy; 304 } 305 306 switch (CS.getKind()) { 307 case ConversionSpecifier::sArg: 308 if (LM.getKind() == LengthModifier::AsWideChar) 309 return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); 310 return ArgTypeResult::CStrTy; 311 case ConversionSpecifier::SArg: 312 // FIXME: This appears to be Mac OS X specific. 313 return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); 314 case ConversionSpecifier::CArg: 315 return ArgTypeResult(Ctx.WCharTy, "wchar_t"); 316 case ConversionSpecifier::pArg: 317 return ArgTypeResult::CPointerTy; 318 default: 319 break; 320 } 321 322 // FIXME: Handle other cases. 323 return ArgTypeResult(); 324} 325 326bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt) { 327 // Handle strings first (char *, wchar_t *) 328 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 329 CS.setKind(ConversionSpecifier::sArg); 330 331 // Disable irrelevant flags 332 HasAlternativeForm = 0; 333 HasLeadingZeroes = 0; 334 335 // Set the long length modifier for wide characters 336 if (QT->getPointeeType()->isWideCharType()) 337 LM.setKind(LengthModifier::AsWideChar); 338 else 339 LM.setKind(LengthModifier::None); 340 341 return true; 342 } 343 344 // We can only work with builtin types. 345 const BuiltinType *BT = QT->getAs<BuiltinType>(); 346 if (!BT) 347 return false; 348 349 // Set length modifier 350 switch (BT->getKind()) { 351 case BuiltinType::Bool: 352 case BuiltinType::WChar_U: 353 case BuiltinType::WChar_S: 354 case BuiltinType::Char16: 355 case BuiltinType::Char32: 356 case BuiltinType::UInt128: 357 case BuiltinType::Int128: 358 case BuiltinType::Half: 359 // Various types which are non-trivial to correct. 360 return false; 361 362#define SIGNED_TYPE(Id, SingletonId) 363#define UNSIGNED_TYPE(Id, SingletonId) 364#define FLOATING_TYPE(Id, SingletonId) 365#define BUILTIN_TYPE(Id, SingletonId) \ 366 case BuiltinType::Id: 367#include "clang/AST/BuiltinTypes.def" 368 // Misc other stuff which doesn't make sense here. 369 return false; 370 371 case BuiltinType::UInt: 372 case BuiltinType::Int: 373 case BuiltinType::Float: 374 case BuiltinType::Double: 375 LM.setKind(LengthModifier::None); 376 break; 377 378 case BuiltinType::Char_U: 379 case BuiltinType::UChar: 380 case BuiltinType::Char_S: 381 case BuiltinType::SChar: 382 LM.setKind(LengthModifier::AsChar); 383 break; 384 385 case BuiltinType::Short: 386 case BuiltinType::UShort: 387 LM.setKind(LengthModifier::AsShort); 388 break; 389 390 case BuiltinType::Long: 391 case BuiltinType::ULong: 392 LM.setKind(LengthModifier::AsLong); 393 break; 394 395 case BuiltinType::LongLong: 396 case BuiltinType::ULongLong: 397 LM.setKind(LengthModifier::AsLongLong); 398 break; 399 400 case BuiltinType::LongDouble: 401 LM.setKind(LengthModifier::AsLongDouble); 402 break; 403 } 404 405 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 406 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) { 407 const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier(); 408 if (Identifier->getName() == "size_t") { 409 LM.setKind(LengthModifier::AsSizeT); 410 } else if (Identifier->getName() == "ssize_t") { 411 // Not C99, but common in Unix. 412 LM.setKind(LengthModifier::AsSizeT); 413 } else if (Identifier->getName() == "intmax_t") { 414 LM.setKind(LengthModifier::AsIntMax); 415 } else if (Identifier->getName() == "uintmax_t") { 416 LM.setKind(LengthModifier::AsIntMax); 417 } else if (Identifier->getName() == "ptrdiff_t") { 418 LM.setKind(LengthModifier::AsPtrDiff); 419 } 420 } 421 422 // Set conversion specifier and disable any flags which do not apply to it. 423 // Let typedefs to char fall through to int, as %c is silly for uint8_t. 424 if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) { 425 CS.setKind(ConversionSpecifier::cArg); 426 LM.setKind(LengthModifier::None); 427 Precision.setHowSpecified(OptionalAmount::NotSpecified); 428 HasAlternativeForm = 0; 429 HasLeadingZeroes = 0; 430 HasPlusPrefix = 0; 431 } 432 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 433 else if (QT->isRealFloatingType()) { 434 CS.setKind(ConversionSpecifier::fArg); 435 } 436 else if (QT->isSignedIntegerType()) { 437 CS.setKind(ConversionSpecifier::dArg); 438 HasAlternativeForm = 0; 439 } 440 else if (QT->isUnsignedIntegerType()) { 441 // Preserve the original formatting, e.g. 'X', 'o'. 442 if (!cast<PrintfConversionSpecifier>(CS).isUIntArg()) 443 CS.setKind(ConversionSpecifier::uArg); 444 HasAlternativeForm = 0; 445 HasPlusPrefix = 0; 446 } else { 447 llvm_unreachable("Unexpected type"); 448 } 449 450 return true; 451} 452 453void PrintfSpecifier::toString(raw_ostream &os) const { 454 // Whilst some features have no defined order, we are using the order 455 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 456 os << "%"; 457 458 // Positional args 459 if (usesPositionalArg()) { 460 os << getPositionalArgIndex() << "$"; 461 } 462 463 // Conversion flags 464 if (IsLeftJustified) os << "-"; 465 if (HasPlusPrefix) os << "+"; 466 if (HasSpacePrefix) os << " "; 467 if (HasAlternativeForm) os << "#"; 468 if (HasLeadingZeroes) os << "0"; 469 470 // Minimum field width 471 FieldWidth.toString(os); 472 // Precision 473 Precision.toString(os); 474 // Length modifier 475 os << LM.toString(); 476 // Conversion specifier 477 os << CS.toString(); 478} 479 480bool PrintfSpecifier::hasValidPlusPrefix() const { 481 if (!HasPlusPrefix) 482 return true; 483 484 // The plus prefix only makes sense for signed conversions 485 switch (CS.getKind()) { 486 case ConversionSpecifier::dArg: 487 case ConversionSpecifier::iArg: 488 case ConversionSpecifier::fArg: 489 case ConversionSpecifier::FArg: 490 case ConversionSpecifier::eArg: 491 case ConversionSpecifier::EArg: 492 case ConversionSpecifier::gArg: 493 case ConversionSpecifier::GArg: 494 case ConversionSpecifier::aArg: 495 case ConversionSpecifier::AArg: 496 return true; 497 498 default: 499 return false; 500 } 501} 502 503bool PrintfSpecifier::hasValidAlternativeForm() const { 504 if (!HasAlternativeForm) 505 return true; 506 507 // Alternate form flag only valid with the oxXaAeEfFgG conversions 508 switch (CS.getKind()) { 509 case ConversionSpecifier::oArg: 510 case ConversionSpecifier::xArg: 511 case ConversionSpecifier::XArg: 512 case ConversionSpecifier::aArg: 513 case ConversionSpecifier::AArg: 514 case ConversionSpecifier::eArg: 515 case ConversionSpecifier::EArg: 516 case ConversionSpecifier::fArg: 517 case ConversionSpecifier::FArg: 518 case ConversionSpecifier::gArg: 519 case ConversionSpecifier::GArg: 520 return true; 521 522 default: 523 return false; 524 } 525} 526 527bool PrintfSpecifier::hasValidLeadingZeros() const { 528 if (!HasLeadingZeroes) 529 return true; 530 531 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 532 switch (CS.getKind()) { 533 case ConversionSpecifier::dArg: 534 case ConversionSpecifier::iArg: 535 case ConversionSpecifier::oArg: 536 case ConversionSpecifier::uArg: 537 case ConversionSpecifier::xArg: 538 case ConversionSpecifier::XArg: 539 case ConversionSpecifier::aArg: 540 case ConversionSpecifier::AArg: 541 case ConversionSpecifier::eArg: 542 case ConversionSpecifier::EArg: 543 case ConversionSpecifier::fArg: 544 case ConversionSpecifier::FArg: 545 case ConversionSpecifier::gArg: 546 case ConversionSpecifier::GArg: 547 return true; 548 549 default: 550 return false; 551 } 552} 553 554bool PrintfSpecifier::hasValidSpacePrefix() const { 555 if (!HasSpacePrefix) 556 return true; 557 558 // The space prefix only makes sense for signed conversions 559 switch (CS.getKind()) { 560 case ConversionSpecifier::dArg: 561 case ConversionSpecifier::iArg: 562 case ConversionSpecifier::fArg: 563 case ConversionSpecifier::FArg: 564 case ConversionSpecifier::eArg: 565 case ConversionSpecifier::EArg: 566 case ConversionSpecifier::gArg: 567 case ConversionSpecifier::GArg: 568 case ConversionSpecifier::aArg: 569 case ConversionSpecifier::AArg: 570 return true; 571 572 default: 573 return false; 574 } 575} 576 577bool PrintfSpecifier::hasValidLeftJustified() const { 578 if (!IsLeftJustified) 579 return true; 580 581 // The left justified flag is valid for all conversions except n 582 switch (CS.getKind()) { 583 case ConversionSpecifier::nArg: 584 return false; 585 586 default: 587 return true; 588 } 589} 590 591bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 592 if (!HasThousandsGrouping) 593 return true; 594 595 switch (CS.getKind()) { 596 case ConversionSpecifier::dArg: 597 case ConversionSpecifier::iArg: 598 case ConversionSpecifier::uArg: 599 case ConversionSpecifier::fArg: 600 case ConversionSpecifier::FArg: 601 case ConversionSpecifier::gArg: 602 case ConversionSpecifier::GArg: 603 return true; 604 default: 605 return false; 606 } 607} 608 609bool PrintfSpecifier::hasValidPrecision() const { 610 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 611 return true; 612 613 // Precision is only valid with the diouxXaAeEfFgGs conversions 614 switch (CS.getKind()) { 615 case ConversionSpecifier::dArg: 616 case ConversionSpecifier::iArg: 617 case ConversionSpecifier::oArg: 618 case ConversionSpecifier::uArg: 619 case ConversionSpecifier::xArg: 620 case ConversionSpecifier::XArg: 621 case ConversionSpecifier::aArg: 622 case ConversionSpecifier::AArg: 623 case ConversionSpecifier::eArg: 624 case ConversionSpecifier::EArg: 625 case ConversionSpecifier::fArg: 626 case ConversionSpecifier::FArg: 627 case ConversionSpecifier::gArg: 628 case ConversionSpecifier::GArg: 629 case ConversionSpecifier::sArg: 630 return true; 631 632 default: 633 return false; 634 } 635} 636bool PrintfSpecifier::hasValidFieldWidth() const { 637 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 638 return true; 639 640 // The field width is valid for all conversions except n 641 switch (CS.getKind()) { 642 case ConversionSpecifier::nArg: 643 return false; 644 645 default: 646 return true; 647 } 648} 649