linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Stefan Kanthak" <kanthak@arcor.de>
To: <linux-kernel@vger.kernel.org>
Subject: [PATCH] vsscanf() in lib/vsprintf.c
Date: Tue, 4 May 2021 21:19:47 +0200	[thread overview]
Message-ID: <6C7CD73845304CDE98F6DB165904B571@H270> (raw)

[-- 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;

             reply	other threads:[~2021-05-04 19:30 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-04 19:19 Stefan Kanthak [this message]
2021-05-05 10:49 ` [PATCH] vsscanf() in lib/vsprintf.c David Laight
2021-05-05 14:35 ` Rasmus Villemoes
2021-05-05 16:41   ` Stefan Kanthak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6C7CD73845304CDE98F6DB165904B571@H270 \
    --to=kanthak@arcor.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).