From patchwork Tue Apr 28 05:36:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 465360 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from whitealder.osuosl.org (whitealder.osuosl.org [140.211.166.138]) by ozlabs.org (Postfix) with ESMTP id 374881400DE for ; Tue, 28 Apr 2015 15:37:23 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="verification failed; unprotected key" header.d=gmail.com header.i=@gmail.com header.b=xd19ioyW; dkim-adsp=none (unprotected policy); dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id D588C8B80F; Tue, 28 Apr 2015 05:37:21 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6qelagK3s-mi; Tue, 28 Apr 2015 05:37:19 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by whitealder.osuosl.org (Postfix) with ESMTP id 7DFAA8B76A; Tue, 28 Apr 2015 05:37:19 +0000 (UTC) X-Original-To: uclibc@lists.busybox.net Delivered-To: uclibc@osuosl.org Received: from whitealder.osuosl.org (whitealder.osuosl.org [140.211.166.138]) by ash.osuosl.org (Postfix) with ESMTP id CF4431C1F6B for ; Tue, 28 Apr 2015 05:37:18 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id C5BFB8B694 for ; Tue, 28 Apr 2015 05:37:18 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SZWsE8Wgq0jr for ; Tue, 28 Apr 2015 05:37:17 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-lb0-f179.google.com (mail-lb0-f179.google.com [209.85.217.179]) by whitealder.osuosl.org (Postfix) with ESMTPS id B3E2F8B6F3 for ; Tue, 28 Apr 2015 05:37:16 +0000 (UTC) Received: by lbcga7 with SMTP id ga7so98769605lbc.1 for ; Mon, 27 Apr 2015 22:37:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=VnPHY1G9+4IXj5lfse90+E3xIndzvDo6M2C9zC9lML0=; b=xd19ioyW9NnB4qAgiTlUyli4tH1VRJzsAFAYiLNCbK55Lt+s8GIexf5x5WmK4qGm6C 1yh4HxLdcZ5GD2FDHqTHk3XHvQs1UlLl1yiKle7nqqKcK5lXEWD2liF93O4XyUN7Mzs2 Ytt/qmrtdwMURtGXNb77L1PzFC691HB2o+9v4y9fEf/Ik6lnE9PiHfNlLdqyROzjLX6C LBm+I44bmk3DB8wdTAx66nbWww9hNmXMdNORPZvRwXDNkoszdyGd3e8EpochELwGJz0K FPz4715Gm+6SQFH4+HTN84eK35bI5392M5obT8nCHNKYAMsUDLyyflatmyO0OfpHc3nO pudg== X-Received: by 10.112.157.164 with SMTP id wn4mr13202168lbb.100.1430199435102; Mon, 27 Apr 2015 22:37:15 -0700 (PDT) Received: from octofox.metropolis ([5.19.183.212]) by mx.google.com with ESMTPSA id u10sm5288617lbb.30.2015.04.27.22.37.13 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Apr 2015 22:37:14 -0700 (PDT) From: Max Filippov To: uclibc@uclibc.org Subject: [PATCH] _scanf.c: Implement 'm' modifier for 'c' and '[' conversions. Date: Tue, 28 Apr 2015 08:36:50 +0300 Message-Id: <1430199410-3095-1-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.8.1.4 Cc: Will Newton , linux-xtensa@linux-xtensa.org X-BeenThere: uclibc@uclibc.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "Discussion and development of uClibc \(the embedded C library\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: uclibc-bounces@uclibc.org Sender: "uClibc" From: Will Newton The current code implements the 'm' modifier only for 's' conversions and would cause a segfault if it was used for 'c' or '[' conversions. This patch extends the code to cover these cases too. The original version could write scanned data outside the passed buffer because index i used in the '[' conversion handling block was clobbered. Signed-off-by: Will Newton Signed-off-by: Max Filippov --- libc/stdio/_scanf.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c index 6ecb3cb..a5828c3 100644 --- a/libc/stdio/_scanf.c +++ b/libc/stdio/_scanf.c @@ -1352,7 +1352,20 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) (psfs.conv_num >= CONV_c) #endif /* __UCLIBC_HAS_WCHAR__ */ { + /* We might have to handle the allocation ourselves */ + int len; + unsigned char **ptr; + b = (psfs.store ? ((unsigned char *) psfs.cur_ptr) : buf); + /* With 'm', we actually got a pointer to a pointer */ + ptr = (void *)b; + + if (psfs.flags & FLAG_MALLOC) { + len = 0; + b = NULL; + } else + len = -1; + fail = 1; if (psfs.conv_num == CONV_c) { @@ -1360,32 +1373,28 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) sc.width = 1; } + if (psfs.flags & FLAG_MALLOC) + b = malloc(sc.width); + + i = 0; while (__scan_getc(&sc) >= 0) { zero_conversions = 0; - *b = sc.cc; - b += psfs.store; + b[i] = sc.cc; + i += psfs.store; } __scan_ungetc(&sc); if (sc.width > 0) { /* Failed to read all required. */ goto DONE; } + if (psfs.flags & FLAG_MALLOC) + *ptr = b; psfs.cnt += psfs.store; goto NEXT_FMT; } if (psfs.conv_num == CONV_s) { - /* We might have to handle the allocation ourselves */ - int len; - /* With 'm', we actually got a pointer to a pointer */ - unsigned char **ptr = (void *)b; i = 0; - if (psfs.flags & FLAG_MALLOC) { - len = 0; - b = NULL; - } else - len = -1; - /* Yes, believe it or not, a %s conversion can store nuls. */ while ((__scan_getc(&sc) >= 0) && !isspace(sc.cc)) { zero_conversions = 0; @@ -1400,10 +1409,6 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) fail = 0; } - if (psfs.flags & FLAG_MALLOC) - *ptr = b; - /* The code below takes care of terminating NUL */ - b += i; } else { #ifdef __UCLIBC_HAS_WCHAR__ assert((psfs.conv_num == CONV_LEFTBRACKET) || \ @@ -1454,13 +1459,20 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) #endif /* __UCLIBC_HAS_WCHAR__ */ + i = 0; while (__scan_getc(&sc) >= 0) { zero_conversions = 0; if (!scanset[sc.cc]) { break; } - *b = sc.cc; - b += psfs.store; + if (i == len) { + /* Pick a size that won't trigger a lot of + * mallocs early on ... */ + len += 256; + b = realloc(b, len + 1); + } + b[i] = sc.cc; + i += psfs.store; fail = 0; } } @@ -1470,6 +1482,9 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg) if (fail) { /* nothing stored! */ goto DONE; } + if (psfs.flags & FLAG_MALLOC) + *ptr = b; + b += i; *b = 0; /* Nul-terminate string. */ psfs.cnt += psfs.store; goto NEXT_FMT;