linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] vsscanf() in lib/vsprintf.c
@ 2021-05-04 19:19 Stefan Kanthak
  2021-05-05 10:49 ` David Laight
  2021-05-05 14:35 ` Rasmus Villemoes
  0 siblings, 2 replies; 4+ messages in thread
From: Stefan Kanthak @ 2021-05-04 19:19 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1517 bytes --]

Hi @ll,

both <https://www.kernel.org/doc/htmldocs/kernel-api/API-sscanf.html>
and <https://www.kernel.org/doc/htmldocs/kernel-api/API-vsscanf.html>
are rather terse and fail to specify the supported arguments and their
conversion specifiers/modifiers.

<https://www.kernel.org/doc/htmldocs/kernel-api/libc.html#id-1.4.3>
tells OTOH:

| The behaviour of these functions may vary slightly from those
| defined by ANSI, and these deviations are noted in the text.

There is but no text (see above) despite multiple deviations from
ANSI C 

<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/lib/vsprintf.c?h=v5.12>

|  /* '%*[' not yet supported, invalid format */
...
|  /*
|   * Warning: This implementation of the '[' conversion specifier
|   * deviates from its glibc counterpart in the following ways:
...

More deviations (just from reading the source):

1. no support for %p
2. no support for conversion modifiers j and t
3. no support for multibyte characters and strings, i.e. %<width>c
   and %<width>s may split UTF-8 codepoints
4. accepts %[<width>]<modifier>[c|s], but ignores all conversion
   modifiers
5. treats %<width><modifier>% (and combinations) as %%
6. accepts %<width><modifier>n (and combinations)
7. doesn't scan the input for %[...]n
8. uses simple_strto[u]l for the conversion modifier z, i.e. assigns
   uint32_t to size_t, resulting in truncation

Is this intended?
If not: patch to fix 5. and 6. and simplify the qualifier handling
        attached 

Stefan Kanthak

[-- Attachment #2: vsprintf.patch --]
[-- Type: application/octet-stream, Size: 1782 bytes --]

--- -/lib/vsprintf.c
+++ +/lib/vsprintf.c
@@ -3287,17 +3287,25 @@
 			str = skip_spaces(str);
 		}
 
+		if (!*fmt)
+			break;
+
 		/* anything that is not a conversion must match exactly */
-		if (*fmt != '%' && *fmt) {
+		if (*fmt != '%') {
 			if (*fmt++ != *str++)
 				break;
 			continue;
 		}
 
-		if (!*fmt)
-			break;
 
+		/* %% must match % */
+		if (*fmt == '%') {
+			if (*fmt++ != *str++)
+				break;
+			continue;
+		}
+
 		/* skip this conversion.
 		 * advance both strings to next white space
 		 */
@@ -3315,6 +3323,13 @@
 			continue;
 		}
 
+		if (*fmt == 'n') {
+			/* return number of characters read so far */
+			*va_arg(args, int *) = str - buf;
+			++fmt;
+			continue;
+		}
+
 		/* get field width */
 		field_width = -1;
 		if (isdigit(*fmt)) {
@@ -3325,30 +3340,18 @@
 
 		/* get conversion qualifier */
 		qualifier = -1;
-		if (*fmt == 'h' || _tolower(*fmt) == 'l' ||
-		    *fmt == 'z') {
+		if (*fmt == 'z' || *fmt == 'L')
 			qualifier = *fmt++;
+		else if (*fmt == 'h' || *fmt == 'l') {
 			if (unlikely(qualifier == *fmt)) {
-				if (qualifier == 'h') {
-					qualifier = 'H';
-					fmt++;
-				} else if (qualifier == 'l') {
-					qualifier = 'L';
-					fmt++;
-				}
+				qualifier = _toupper(qualifier);
+				fmt++;
 			}
 		}
 
 		if (!*fmt)
 			break;
 
-		if (*fmt == 'n') {
-			/* return number of characters read so far */
-			*va_arg(args, int *) = str - buf;
-			++fmt;
-			continue;
-		}
-
 		if (!*str)
 			break;
 
@@ -3450,11 +3453,6 @@
 			fallthrough;
 		case 'u':
 			break;
-		case '%':
-			/* looking for '%' in str */
-			if (*str++ != '%')
-				return num;
-			continue;
 		default:
 			/* invalid format; stop here */
 			return num;

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-05-05 16:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-04 19:19 [PATCH] vsscanf() in lib/vsprintf.c Stefan Kanthak
2021-05-05 10:49 ` David Laight
2021-05-05 14:35 ` Rasmus Villemoes
2021-05-05 16:41   ` Stefan Kanthak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).