1*ce204681Srillig /* $NetBSD: msg_358.c,v 1.4 2024/11/05 06:23:04 rillig Exp $ */ 238c0bdf2Srillig # 3 "msg_358.c" 338c0bdf2Srillig 438c0bdf2Srillig // Test for message: hex escape '%.*s' has more than 2 digits [358] 538c0bdf2Srillig 638c0bdf2Srillig /* 738c0bdf2Srillig * In the format argument of the snprintb and snprintb_m functions, a bit 838c0bdf2Srillig * position or field width is written as an octal or hexadecimal escape 9*ce204681Srillig * sequence. If the description that follows a hexadecimal escape sequence 10*ce204681Srillig * starts with hexadecimal digits (A-Fa-f), these digits are still part of the 11*ce204681Srillig * escape sequence instead of the description. 12*ce204681Srillig * 13*ce204681Srillig * All platforms supported by lint have 8-bit char, so using more than the 14*ce204681Srillig * maximum necessary 2 hexadecimal digits in an escape sequence is suspicious 15*ce204681Srillig * of being unintended. 1638c0bdf2Srillig */ 1738c0bdf2Srillig 1838c0bdf2Srillig /* lint1-extra-flags: -X 351 */ 1938c0bdf2Srillig 2038c0bdf2Srillig typedef typeof(sizeof(0)) size_t; 2138c0bdf2Srillig typedef unsigned long long uint64_t; 2238c0bdf2Srillig 2338c0bdf2Srillig int snprintb(char *, size_t, const char *, uint64_t); 2438c0bdf2Srillig 2538c0bdf2Srillig void 2638c0bdf2Srillig examples(unsigned u32, uint64_t u64) 2738c0bdf2Srillig { 2838c0bdf2Srillig char buf[64]; 2938c0bdf2Srillig 3038c0bdf2Srillig /* expect+3: warning: hex escape '\x01B' has more than 2 digits [358] */ 3138c0bdf2Srillig snprintb(buf, sizeof(buf), 3238c0bdf2Srillig "\020\x01BIT", 3338c0bdf2Srillig u32); 3438c0bdf2Srillig 3538c0bdf2Srillig /* expect+3: warning: hex escape '\x01b' has more than 2 digits [358] */ 3638c0bdf2Srillig snprintb(buf, sizeof(buf), 3738c0bdf2Srillig "\020\x01bit", 3838c0bdf2Srillig u32); 3938c0bdf2Srillig 4038c0bdf2Srillig // This mismatch goes undetected as it has only 2 digits, does not mix 4138c0bdf2Srillig // case and is in bounds. A spellchecker could mark the unknown word 4238c0bdf2Srillig // 'ield' to give a hint. 4338c0bdf2Srillig snprintb(buf, sizeof(buf), 4438c0bdf2Srillig "\020\x1FIELD", 4538c0bdf2Srillig u32); 4638c0bdf2Srillig 4738c0bdf2Srillig /* expect+3: warning: hex escape '\x01b' has more than 2 digits [358] */ 4838c0bdf2Srillig snprintb(buf, sizeof(buf), 4938c0bdf2Srillig "\177\020b\x01bit\0", 5038c0bdf2Srillig u64); 5138c0bdf2Srillig 5238c0bdf2Srillig /* expect+3: warning: hex escape '\x02b' has more than 2 digits [358] */ 5338c0bdf2Srillig snprintb(buf, sizeof(buf), 5438c0bdf2Srillig "\177\020f\x00\x02bit\0", 5538c0bdf2Srillig u64); 563d5fc263Srillig 573d5fc263Srillig // In this example from the snprintb manual page, the descriptions 583d5fc263Srillig // that start with a hexadecimal digit must be separated from the 593d5fc263Srillig // hexadecimal escape sequence for the bit position. 603d5fc263Srillig snprintb(buf, sizeof(buf), 613d5fc263Srillig "\20\x10NOTBOOT\x0f" "FPP\x0eSDVMA\x0cVIDEO" 623d5fc263Srillig "\x0bLORES\x0a" "FPA\x09" "DIAG\x07" "CACHE" 633d5fc263Srillig "\x06IOCACHE\x05LOOPBACK\x04" "DBGCACHE", 643d5fc263Srillig u32); 6538c0bdf2Srillig } 66