From patchwork Tue Apr 26 20:46:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 66731 Delivered-To: patch@linaro.org Received: by 10.140.93.198 with SMTP id d64csp1826611qge; Tue, 26 Apr 2016 13:47:09 -0700 (PDT) X-Received: by 10.98.51.132 with SMTP id z126mr6469251pfz.23.1461703629723; Tue, 26 Apr 2016 13:47:09 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id f22si433287pfj.46.2016.04.26.13.47.09 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Apr 2016 13:47:09 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-69179-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-69179-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-69179-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=r6jHT1Zf8qCpFw0tSwa1upOpYj8z5uhZ6Qa7E8asKW0tRxho5kvnK PR7X1liE+ib0eCR2jWgt4pjMWDSKoqCGOG/+2FYx14j/2uOHOJxBVufxC9AG8NW1 zZm4COHdKEyPxbEhX+6Dg7LiukPVMd0NQoDpfgtOcsK0ZbMJk+tciA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=SxAIGsUMqdlacUgqvlihjFTX9mg=; b=rjLkTsnLtJJhbuvd6oV95Zbs0svf aEdw2HCqe/IGRMVr8EgpeqEJu27YwcU2oBEfTsmjvi33Ijf4wVZv9KIEYj5vWJBX S1idRa1OBKbTUi7IrkxboRognhFGrOKxFG43dGKKB5FQSkcNQS73xoXbnKhjHSxy zuZBQjlXq8jD2Zs= Received: (qmail 113928 invoked by alias); 26 Apr 2016 20:46:58 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 113904 invoked by uid 89); 26 Apr 2016 20:46:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=1930, 1, 71, test_function, UD:test-skeleton.c X-HELO: mail-yw0-f176.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=0YCEhdL9QasrMCBBQoKnN7gT5YAx4TG1Hp9HOVDTtp4=; b=X5ASLqMyeDOXOQRlkaAnxzl5QV8qZvLdwGug9GJCK3rWSRo+yR6WaK+gWBtXJKY7im 7WwdH2SGklB8XytyE37akti8vJPNA5Fefz+dh4xD5DnIjZDmZT8FaFeVgqDn5saE+4LK 5p9GwO0rRrsqjg2EamQHHBxkBgN9wqMVpb0vuHd2VBF6mdcKZnPPEuC6k4AnQ9bKJJgN lwP4Z67MBL6z59YGoP5UezX3Ik0pfv4fTPENzS39rGn821XhnhsRe0uhXnKTg8ZuOKKO EDb53ApY1OalQMdWZbuKy1w7K48CiTIZO1M1aNtfLVTJjoOykT3j+fzMTfVmlnO1VrQQ NDFw== X-Gm-Message-State: AOPr4FV0qscAhRVj2M+NIO+wOGDpNeO/RslGafOWw3oFGu4ufv/j166ZGuoG0ctR+UzJ3c1h X-Received: by 10.13.243.5 with SMTP id c5mr3032930ywf.40.1461703605592; Tue, 26 Apr 2016 13:46:45 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [COMMITTED] libio: Update internal fmemopen position after write (BZ #20005) Date: Tue, 26 Apr 2016 17:46:36 -0300 Message-Id: <1461703596-21151-1-git-send-email-adhemerval.zanella@linaro.org> Current GLIBC fmemopen fails with a simple testcase: char buffer[500] = "x"; FILE *stream; stream = fmemopen(buffer, 500, "r+"); fwrite("fish",sizeof(char),5,stream); printf("pos-1:%ld\n",ftell(stream)); fflush(stream); printf("pos-2:%ld\n",ftell(stream)); It returns: pos-1:5 pos-2:0 Where it should return: pos-1:5 pos-2:5 This is due the internal write function does not correctly update the internal object position state and then the seek operation returns a wrong value. This patch fixes it. It fixes both BZ #20005 and BZ #19230 (marked as duplicated). A new test is added to check for such case. Tested on x86_64 and i686. * libio/fmemopen.c (fmemopen_write): Update internal position after write. * stdio-common/Makefile (tests): Add tst-fmemopen4.c. * stdio-common/tst-fmemopen4.c: New file.. --- ChangeLog | 8 +++++ libio/fmemopen.c | 6 ++-- stdio-common/Makefile | 2 +- stdio-common/tst-fmemopen4.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 stdio-common/tst-fmemopen4.c -- 2.7.4 diff --git a/ChangeLog b/ChangeLog index 5d6ea9e..6fda4a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-04-26 Adhemerval Zanella + + [BZ #20005] + * libio/fmemopen.c (fmemopen_write): Update internal position after + write. + * stdio-common/Makefile (tests): Add tst-fmemopen4.c. + * stdio-common/tst-fmemopen4.c: New file.. + 2016-04-26 Joseph Myers [BZ #19996] diff --git a/libio/fmemopen.c b/libio/fmemopen.c index 23b5c5f..9264b72 100644 --- a/libio/fmemopen.c +++ b/libio/fmemopen.c @@ -86,10 +86,10 @@ fmemopen_write (void *cookie, const char *b, size_t s) memcpy (&(c->buffer[pos]), b, s); - pos += s; - if ((size_t) pos > c->maxpos) + c->pos += s; + if ((size_t) c->pos > c->maxpos) { - c->maxpos = pos; + c->maxpos = c->pos; if (addnullc) c->buffer[c->maxpos] = '\0'; } diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 6c597c1..4c4834b 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -58,7 +58,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \ scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \ bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \ bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 \ - tst-printf-bz18872 tst-vfprintf-width-prec + tst-printf-bz18872 tst-vfprintf-width-prec tst-fmemopen4 test-srcs = tst-unbputc tst-printf diff --git a/stdio-common/tst-fmemopen4.c b/stdio-common/tst-fmemopen4.c new file mode 100644 index 0000000..e24f1ca --- /dev/null +++ b/stdio-common/tst-fmemopen4.c @@ -0,0 +1,71 @@ +/* fmemopen tests for BZ#1930 and BZ#20005. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + + +/* Check if fflush does not reset the file position. */ +static int +do_test (void) +{ + char buffer[500] = "x"; + + FILE *stream = fmemopen (buffer, sizeof (buffer), "r+"); + if (stream == NULL) + { + printf ("error: fmemopen could not open stream\n"); + return 1; + } + + const char test[] = "test"; + + size_t r = fwrite (test, sizeof (char), sizeof (test), stream); + if (r != sizeof (test)) + { + printf ("error: fwrite returned %zu, expected %zu\n", r, sizeof(test)); + return 1; + } + + r = ftell (stream); + if (r != sizeof (test)) + { + printf ("error: ftell return %zu, expected %zu\n", r, sizeof(test)); + return 1; + } + + if (fflush (stream) != 0) + { + printf ("error: fflush failed\n"); + return 1; + } + + r = ftell (stream); + if (r != sizeof (test)) + { + printf ("error: ftell return %zu, expected %zu\n", r, sizeof(test)); + return 1; + } + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c"