Skip to content

Commit

Permalink
Fix BZ #18872 -- memory leak in printf_positional.
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Pluzhnikov committed Sep 16, 2015
1 parent 1f60740 commit 560b044
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 2 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
2015-09-16 Paul Eggert <eggert@cs.ucla.edu>
Paul Pluzhnikov <ppluzhnikov@google.com>

[BZ #18872]
* stdio-common/Makefile (tst-printf-bz18872): New test.
(tst-printf-bz18872-mem.out): Likewise.
* stdio-common/tst-printf-bz18872.sh: Generate new test.
* stdio-common/vfprintf.c: Fix memory leaks.

2015-09-16 Andreas Schwab <schwab@suse.de>

[BZ #17244]
Expand Down
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Version 2.23
18084, 18086, 18240, 18265, 18370, 18421, 18480, 18525, 18595, 18610,
18618, 18647, 18661, 18674, 18675, 18681, 18757, 18778, 18781, 18787,
18789, 18790, 18795, 18796, 18820, 18823, 18824, 18857, 18863, 18870,
18873, 18875, 18887, 18921, 18952, 18961, 18966, 18967.
18872, 18873, 18875, 18887, 18921, 18952, 18961, 18966, 18967.

* The obsolete header <regexp.h> has been removed. Programs that require
this header must be updated to use <regex.h> instead.
Expand Down
17 changes: 16 additions & 1 deletion stdio-common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,23 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
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
bug25 tst-printf-round bug23-2 bug23-3 bug23-4 bug26 tst-fmemopen3 \
tst-printf-bz18872

test-srcs = tst-unbputc tst-printf

ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-unbputc.out $(objpfx)tst-printf.out \
$(objpfx)tst-printf-bz18872-mem.out \
$(objpfx)tst-setvbuf1-cmp.out
generated += tst-printf-bz18872.c tst-printf-bz18872.mtrace \
tst-printf-bz18872-mem.out
endif

include ../Rules

tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace

ifeq ($(run-built-tests),yes)
$(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
Expand All @@ -76,6 +82,15 @@ $(objpfx)tst-unbputc.out: tst-unbputc.sh $(objpfx)tst-unbputc
$(objpfx)tst-printf.out: tst-printf.sh $(objpfx)tst-printf
$(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
$(evaluate-test)

# We generate this source because it requires a printf invocation with
# 10K arguments.
$(objpfx)tst-printf-bz18872.c: tst-printf-bz18872.sh
rm -f $@ && $(BASH) $^ > $@.new && mv $@.new $@

$(objpfx)tst-printf-bz18872-mem.out: $(objpfx)tst-printf-bz18872.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-printf-bz18872.mtrace > $@; \
$(evaluate-test)
endif

CFLAGS-vfprintf.c = -Wno-uninitialized
Expand Down
70 changes: 70 additions & 0 deletions stdio-common/tst-printf-bz18872.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/bin/bash
# Copyright (C) 2015 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
# <http://www.gnu.org/licenses/>.

# To test BZ #18872, we need a printf() with 10K arguments.
# Such a printf could be generated with non-trivial macro
# application, but it's simpler to generate the test source
# via this script.

n_args=10000

cat <<'EOF'
#include <stdio.h>
#include <mcheck.h>
/*
Compile do_test without optimization: GCC 4.9/5.0/6.0 takes a long time
to build this source. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67396 */
#pragma GCC push_options
#pragma GCC optimize ("-O0")
int do_test (void)
{
mtrace ();
printf (
EOF

for ((j = 0; j < $n_args / 10; j++)); do
for ((k = 0; k < 10; k++)); do
printf '"%%%d$s" ' $((10 * $j + $k + 1))
done
printf "\n"
done

printf '"%%%d$s",\n' $(($n_args + 1))

for ((j = 0; j < $n_args / 10; j++)); do
for ((k = 0; k < 10; k++)); do
printf '"a", '
done
printf " /* %4d */\n" $((10 * $j + $k))
done

printf '"\\n");'


cat <<'EOF'
return 0;
}
#pragma GCC pop_options
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
EOF
4 changes: 4 additions & 0 deletions stdio-common/vfprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2091,6 +2091,10 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format,
- specs[nspecs_done].end_of_fmt);
}
all_done:
if (__glibc_unlikely (specs_malloced))
free (specs);
if (__glibc_unlikely (args_malloced != NULL))
free (args_malloced);
if (__glibc_unlikely (workstart != NULL))
free (workstart);
return done;
Expand Down

0 comments on commit 560b044

Please sign in to comment.