Compare commits
6 Commits
Author | SHA1 | Date |
---|---|---|
Kamil Dudka | 05700be3a8 | |
Ondřej Vašík | cf046ddd69 | |
Ondřej Vašík | def16b2b28 | |
Ondřej Vašík | 8a2e75b799 | |
Jesse Keating | 67d4ad96a5 | |
Ondřej Vašík | 626aa7bd2c |
|
@ -0,0 +1,11 @@
|
|||
diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am
|
||||
--- coreutils-8.4-orig/src/Makefile.am 2010-09-03 17:34:43.399747649 +0200
|
||||
+++ coreutils-8.4/src/Makefile.am 2010-09-03 17:36:13.005765125 +0200
|
||||
@@ -367,6 +367,7 @@ factor_LDADD += $(LIB_GMP)
|
||||
|
||||
# for crypt
|
||||
su_LDADD += $(LIB_CRYPT) @LIB_PAM@
|
||||
+su_LDFLAGS = -pie -Wl,-z,relro,-z,now
|
||||
|
||||
# for various ACL functions
|
||||
copy_LDADD += $(LIB_ACL)
|
|
@ -0,0 +1,66 @@
|
|||
From b3959fc691e606857a3c6e9b316ec34819972245 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Meyering <meyering@redhat.com>
|
||||
Date: Sat, 28 Aug 2010 17:45:29 +0200
|
||||
Subject: [PATCH] tac: avoid double free
|
||||
|
||||
* src/tac.c (main): Reading a line longer than 16KiB would cause
|
||||
tac to realloc its primary buffer. Then, just before exit, tac
|
||||
would mistakenly free the original (now free'd) buffer.
|
||||
This bug was introduced by commit be6c13e7, "maint: always free a
|
||||
buffer, to avoid even semblance of a leak".
|
||||
* tests/misc/tac (double-free): New test, to exercise this.
|
||||
Reported by Salvo Tomaselli in <http://bugs.debian.org/594666>.
|
||||
---
|
||||
src/tac.c | 6 ++++--
|
||||
tests/misc/tac | 6 ++++++
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/tac.c b/src/tac.c
|
||||
index cec9736..859e006 100644
|
||||
--- a/src/tac.c
|
||||
+++ b/src/tac.c
|
||||
@@ -633,7 +633,6 @@ main (int argc, char **argv)
|
||||
if (! (read_size < half_buffer_size && half_buffer_size < G_buffer_size))
|
||||
xalloc_die ();
|
||||
G_buffer = xmalloc (G_buffer_size);
|
||||
- void *buf = G_buffer;
|
||||
if (sentinel_length)
|
||||
{
|
||||
strcpy (G_buffer, separator);
|
||||
@@ -666,6 +665,9 @@ main (int argc, char **argv)
|
||||
error (0, errno, "-");
|
||||
ok = false;
|
||||
}
|
||||
- free (buf);
|
||||
+
|
||||
+ size_t offset = sentinel_length ? sentinel_length : 1;
|
||||
+ free (G_buffer - offset);
|
||||
+
|
||||
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
diff --git a/tests/misc/tac b/tests/misc/tac
|
||||
index 7631049..4130c00 100755
|
||||
--- a/tests/misc/tac
|
||||
+++ b/tests/misc/tac
|
||||
@@ -24,6 +24,9 @@ my $prog = 'tac';
|
||||
|
||||
my $bad_dir = 'no/such/dir';
|
||||
|
||||
+# This must be longer than 16KiB to trigger the double free in coreutils-8.5.
|
||||
+my $long_line = 'o' x (16 * 1024 + 1);
|
||||
+
|
||||
my @Tests =
|
||||
(
|
||||
['segfault', '-r', {IN=>"a\n"}, {IN=>"b\n"}, {OUT=>"a\nb\n"}],
|
||||
@@ -67,6 +70,9 @@ my @Tests =
|
||||
{ERR_SUBST => "s,`$bad_dir': .*,...,"},
|
||||
{ERR => "$prog: cannot create temporary file in ...\n"},
|
||||
{EXIT => 1}],
|
||||
+
|
||||
+ # coreutils-8.5's tac would double-free its primary buffer.
|
||||
+ ['double-free', {IN=>$long_line}, {OUT=>$long_line}],
|
||||
);
|
||||
|
||||
@Tests = triple_test \@Tests;
|
||||
--
|
||||
1.7.2.2.510.g7180a
|
|
@ -0,0 +1,431 @@
|
|||
From: Pádraig Brady <P@draigBrady.com>
|
||||
Date: Mon, 27 Sep 2010 06:16:44 +0000 (+0100)
|
||||
Subject: tr: fix various issues with case conversion
|
||||
X-Git-Url: http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff_plain;h=3f48829c;hp=704eedab034e24814067c535d3577f165c9a8b68
|
||||
|
||||
tr: fix various issues with case conversion
|
||||
|
||||
This valid translation spec aborted:
|
||||
LC_ALL=en_US.iso-8859-1 tr '[:upper:]- ' '[:lower:]_'
|
||||
This invalid translation spec aborted:
|
||||
LC_ALL=en_US.iso-8859-1 tr '[:upper:] ' '[:lower:]'
|
||||
This was caused by commit 6efd1046, 05-01-2008,
|
||||
"Avoid tr case-conversion failure in some locales"
|
||||
|
||||
This misaligned conversion spec was allowed:
|
||||
LC_ALL=C tr 'A-Y[:lower:]' 'a-z[:upper:]'
|
||||
This was caused by commit af5d0c36, 21-10-2007,
|
||||
"tr: do not reject an unmatched [:lower:] or [:upper:] in SET1"
|
||||
|
||||
This misaligned spec was allowed by extending the class:
|
||||
LC_ALL=C tr '[:upper:] ' '[:lower:]'
|
||||
|
||||
* src/tr.c (validate_case_classes): A new function to check
|
||||
alignment of case conversion classes. Also it adjusts the
|
||||
length of the sets so that locales with different numbers of
|
||||
upper and lower case characters, don't cause issues.
|
||||
(string2_extend): Disallow extending the case conversion
|
||||
class as in the above example. That is locale dependent
|
||||
and most likely not what the user wants.
|
||||
(validate): Do the simple test for "restricted" char classes
|
||||
earlier, so we don't redundantly do more expensive validation.
|
||||
(main): Remove the case class validation, and simplify.
|
||||
* tests/misc/tr-case-class: A new test to test the various
|
||||
alignment and locale issues, associated with case conversion.
|
||||
* tests/misc/tr: Move case conversion tests to new tr-case-class.
|
||||
* tests/Makefile.am: Reference the new test.
|
||||
---
|
||||
|
||||
diff --git a/src/tr.c b/src/tr.c
|
||||
index a5b6810..479d3d3 100644
|
||||
--- a/src/tr.c
|
||||
+++ b/src/tr.c
|
||||
@@ -1177,6 +1177,78 @@ card_of_complement (struct Spec_list *s)
|
||||
return cardinality;
|
||||
}
|
||||
|
||||
+/* Discard the lengths associated with a case conversion,
|
||||
+ as using the actual number of upper or lower case characters
|
||||
+ is problematic when they don't match in some locales.
|
||||
+ Also ensure the case conversion classes in string2 are
|
||||
+ aligned correctly with those in string1.
|
||||
+ Note POSIX says the behavior of `tr "[:upper:]" "[:upper:]"'
|
||||
+ is undefined. Therefore we allow it (unlike Solaris)
|
||||
+ and treat it as a no-op. */
|
||||
+
|
||||
+static void
|
||||
+validate_case_classes (struct Spec_list *s1, struct Spec_list *s2)
|
||||
+{
|
||||
+ size_t n_upper = 0;
|
||||
+ size_t n_lower = 0;
|
||||
+ unsigned int i;
|
||||
+ int c1 = 0;
|
||||
+ int c2 = 0;
|
||||
+ count old_s1_len = s1->length;
|
||||
+ count old_s2_len = s2->length;
|
||||
+ struct List_element *s1_tail = s1->tail;
|
||||
+ struct List_element *s2_tail = s2->tail;
|
||||
+ bool s1_new_element = true;
|
||||
+ bool s2_new_element = true;
|
||||
+
|
||||
+ if (!s2->has_char_class)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < N_CHARS; i++)
|
||||
+ {
|
||||
+ if (isupper (i))
|
||||
+ n_upper++;
|
||||
+ if (islower (i))
|
||||
+ n_lower++;
|
||||
+ }
|
||||
+
|
||||
+ s1->state = BEGIN_STATE;
|
||||
+ s2->state = BEGIN_STATE;
|
||||
+
|
||||
+ while (c1 != -1 && c2 != -1)
|
||||
+ {
|
||||
+ enum Upper_Lower_class class_s1, class_s2;
|
||||
+
|
||||
+ c1 = get_next (s1, &class_s1);
|
||||
+ c2 = get_next (s2, &class_s2);
|
||||
+
|
||||
+ /* If c2 transitions to a new case class, then
|
||||
+ c1 must also transition at the same time. */
|
||||
+ if (s2_new_element && class_s2 != UL_NONE
|
||||
+ && !(s1_new_element && class_s1 != UL_NONE))
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ _("misaligned [:upper:] and/or [:lower:] construct"));
|
||||
+
|
||||
+ /* If case converting, quickly skip over the elements. */
|
||||
+ if (class_s2 != UL_NONE)
|
||||
+ {
|
||||
+ skip_construct (s1);
|
||||
+ skip_construct (s2);
|
||||
+ /* Discount insignificant/problematic lengths. */
|
||||
+ s1->length -= (class_s1 == UL_UPPER ? n_upper : n_lower) - 1;
|
||||
+ s2->length -= (class_s2 == UL_UPPER ? n_upper : n_lower) - 1;
|
||||
+ }
|
||||
+
|
||||
+ s1_new_element = s1->state == NEW_ELEMENT; /* Next element is new. */
|
||||
+ s2_new_element = s2->state == NEW_ELEMENT; /* Next element is new. */
|
||||
+ }
|
||||
+
|
||||
+ assert (old_s1_len >= s1->length && old_s2_len >= s2->length);
|
||||
+
|
||||
+ s1->tail = s1_tail;
|
||||
+ s2->tail = s2_tail;
|
||||
+}
|
||||
+
|
||||
/* Gather statistics about the spec-list S in preparation for the tests
|
||||
in validate that determine the consistency of the specs. This function
|
||||
is called at most twice; once for string1, and again for any string2.
|
||||
@@ -1318,20 +1390,14 @@ parse_str (char const *s, struct Spec_list *spec_list)
|
||||
Upon successful completion, S2->length is set to S1->length. The only
|
||||
way this function can fail to make S2 as long as S1 is when S2 has
|
||||
zero-length, since in that case, there is no last character to repeat.
|
||||
- So S2->length is required to be at least 1.
|
||||
+ So S2->length is required to be at least 1. */
|
||||
|
||||
- Providing this functionality allows the user to do some pretty
|
||||
- non-BSD (and non-portable) things: For example, the command
|
||||
- tr -cs '[:upper:]0-9' '[:lower:]'
|
||||
- is almost guaranteed to give results that depend on your collating
|
||||
- sequence. */
|
||||
|
||||
static void
|
||||
string2_extend (const struct Spec_list *s1, struct Spec_list *s2)
|
||||
{
|
||||
struct List_element *p;
|
||||
unsigned char char_to_repeat;
|
||||
- int i;
|
||||
|
||||
assert (translating);
|
||||
assert (s1->length > s2->length);
|
||||
@@ -1347,11 +1413,13 @@ string2_extend (const struct Spec_list *s1, struct Spec_list *s2)
|
||||
char_to_repeat = p->u.range.last_char;
|
||||
break;
|
||||
case RE_CHAR_CLASS:
|
||||
- for (i = N_CHARS - 1; i >= 0; i--)
|
||||
- if (is_char_class_member (p->u.char_class, i))
|
||||
- break;
|
||||
- assert (i >= 0);
|
||||
- char_to_repeat = i;
|
||||
+ /* Note BSD allows extending of classes in string2. For example:
|
||||
+ tr '[:upper:]0-9' '[:lower:]'
|
||||
+ That's not portable however, contradicts POSIX and is dependent
|
||||
+ on your collating sequence. */
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ _("when translating with string1 longer than string2,\n\
|
||||
+the latter string must not end with a character class"));
|
||||
break;
|
||||
|
||||
case RE_REPEATED_CHAR:
|
||||
@@ -1431,6 +1499,15 @@ validate (struct Spec_list *s1, struct Spec_list *s2)
|
||||
when translating"));
|
||||
}
|
||||
|
||||
+ if (s2->has_restricted_char_class)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ _("when translating, the only character classes that may \
|
||||
+appear in\nstring2 are `upper' and `lower'"));
|
||||
+ }
|
||||
+
|
||||
+ validate_case_classes (s1, s2);
|
||||
+
|
||||
if (s1->length > s2->length)
|
||||
{
|
||||
if (!truncate_set1)
|
||||
@@ -1452,13 +1529,6 @@ when translating"));
|
||||
_("when translating with complemented character classes,\
|
||||
\nstring2 must map all characters in the domain to one"));
|
||||
}
|
||||
-
|
||||
- if (s2->has_restricted_char_class)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0,
|
||||
- _("when translating, the only character classes that may \
|
||||
-appear in\nstring2 are `upper' and `lower'"));
|
||||
- }
|
||||
}
|
||||
else
|
||||
/* Not translating. */
|
||||
@@ -1812,7 +1882,6 @@ main (int argc, char **argv)
|
||||
{
|
||||
int c1, c2;
|
||||
int i;
|
||||
- bool case_convert = false;
|
||||
enum Upper_Lower_class class_s1;
|
||||
enum Upper_Lower_class class_s2;
|
||||
|
||||
@@ -1822,47 +1891,21 @@ main (int argc, char **argv)
|
||||
s2->state = BEGIN_STATE;
|
||||
for (;;)
|
||||
{
|
||||
- /* When the previous pair identified case-converting classes,
|
||||
- advance S1 and S2 so that each points to the following
|
||||
- construct. */
|
||||
- if (case_convert)
|
||||
- {
|
||||
- skip_construct (s1);
|
||||
- skip_construct (s2);
|
||||
- case_convert = false;
|
||||
- }
|
||||
-
|
||||
c1 = get_next (s1, &class_s1);
|
||||
c2 = get_next (s2, &class_s2);
|
||||
|
||||
- /* When translating and there is an [:upper:] or [:lower:]
|
||||
- class in SET2, then there must be a corresponding [:lower:]
|
||||
- or [:upper:] class in SET1. */
|
||||
- if (class_s1 == UL_NONE
|
||||
- && (class_s2 == UL_LOWER || class_s2 == UL_UPPER))
|
||||
- error (EXIT_FAILURE, 0,
|
||||
- _("misaligned [:upper:] and/or [:lower:] construct"));
|
||||
-
|
||||
if (class_s1 == UL_LOWER && class_s2 == UL_UPPER)
|
||||
{
|
||||
- case_convert = true;
|
||||
for (i = 0; i < N_CHARS; i++)
|
||||
if (islower (i))
|
||||
xlate[i] = toupper (i);
|
||||
}
|
||||
else if (class_s1 == UL_UPPER && class_s2 == UL_LOWER)
|
||||
{
|
||||
- case_convert = true;
|
||||
for (i = 0; i < N_CHARS; i++)
|
||||
if (isupper (i))
|
||||
xlate[i] = tolower (i);
|
||||
}
|
||||
- else if ((class_s1 == UL_LOWER && class_s2 == UL_LOWER)
|
||||
- || (class_s1 == UL_UPPER && class_s2 == UL_UPPER))
|
||||
- {
|
||||
- /* POSIX says the behavior of `tr "[:upper:]" "[:upper:]"'
|
||||
- is undefined. Treat it as a no-op. */
|
||||
- }
|
||||
else
|
||||
{
|
||||
/* The following should have been checked by validate... */
|
||||
@@ -1870,6 +1913,13 @@ main (int argc, char **argv)
|
||||
break;
|
||||
xlate[c1] = c2;
|
||||
}
|
||||
+
|
||||
+ /* When case-converting, skip the elements as an optimization. */
|
||||
+ if (class_s2 != UL_NONE)
|
||||
+ {
|
||||
+ skip_construct (s1);
|
||||
+ skip_construct (s2);
|
||||
+ }
|
||||
}
|
||||
assert (c1 == -1 || truncate_set1);
|
||||
}
|
||||
diff --git a/tests/Makefile.am b/tests/Makefile.am
|
||||
index 5619d0b..3236637 100644
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -260,6 +260,7 @@ TESTS = \
|
||||
misc/timeout \
|
||||
misc/timeout-parameters \
|
||||
misc/tr \
|
||||
+ misc/tr-case-class \
|
||||
misc/truncate-dangling-symlink \
|
||||
misc/truncate-dir-fail \
|
||||
misc/truncate-fail-diag \
|
||||
diff --git a/tests/misc/tr b/tests/misc/tr
|
||||
index ca7a960..00cd8e6 100755
|
||||
--- a/tests/misc/tr
|
||||
+++ b/tests/misc/tr
|
||||
@@ -155,34 +155,8 @@ my @Tests =
|
||||
|
||||
# Up to coreutils-6.9, this would provoke a failed assertion.
|
||||
['no-abort-1', qw(-c a '[b*256]'), {IN=>'abc'}, {OUT=>'abb'}],
|
||||
-
|
||||
- # Up to coreutils-6.9, tr rejected an unmatched [:lower:] or [:upper:] in SET1.
|
||||
- ['s1-lower', qw('[:lower:]' '[.*]'),
|
||||
- {IN=>'#$%123abcABC'}, {OUT=>'#$%123...ABC'}],
|
||||
- ['s1-upper', qw('[:upper:]' '[.*]'),
|
||||
- {IN=>'#$%123abcABC'}, {OUT=>'#$%123abc...'}],
|
||||
-
|
||||
- # Up to coreutils-6.9.91, this would fail with the diagnostic:
|
||||
- # tr: misaligned [:upper:] and/or [:lower:] construct
|
||||
- # with LC_CTYPE=en_US.ISO-8859-1.
|
||||
- ['tolower-F', qw('[:upper:]' '[:lower:]'), {IN=>'A'}, {OUT=>'a'}],
|
||||
-
|
||||
- # When doing a case-converting translation with something after the
|
||||
- # [:upper:] and [:lower:] elements, ensure that tr honors the following byte.
|
||||
- ['upcase-xtra', qw('[:lower:].' '[:upper:]x'), {IN=>'abc.'}, {OUT=>'ABCx'}],
|
||||
- ['dncase-xtra', qw('[:upper:].' '[:lower:]x'), {IN=>'ABC.'}, {OUT=>'abcx'}],
|
||||
);
|
||||
|
||||
-# Set LC_CTYPE=en_US.ISO-8859-1 in the environment of the tolower-F test.
|
||||
-foreach my $t (@Tests)
|
||||
- {
|
||||
- if ($t->[0] eq 'tolower-F')
|
||||
- {
|
||||
- push @$t, {ENV=>'LC_CTYPE=en_US.ISO-8859-1'};
|
||||
- last;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
@Tests = triple_test \@Tests;
|
||||
|
||||
# tr takes its input only from stdin, not from a file argument, so
|
||||
diff --git a/tests/misc/tr-case-class b/tests/misc/tr-case-class
|
||||
new file mode 100755
|
||||
index 0000000..d81c676
|
||||
--- /dev/null
|
||||
+++ b/tests/misc/tr-case-class
|
||||
@@ -0,0 +1,112 @@
|
||||
+#!/bin/sh
|
||||
+# Test case conversion classes
|
||||
+
|
||||
+# Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software: you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+
|
||||
+# This program 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 General Public License for more details.
|
||||
+
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+. $srcdir/test-lib.sh
|
||||
+
|
||||
+# Ensure we support translation of case classes with extension
|
||||
+echo '01234567899999999999999999' > exp
|
||||
+echo 'abcdefghijklmnopqrstuvwxyz' |
|
||||
+tr '[:lower:]' '0-9' > out || fail=1
|
||||
+compare out exp || fail=1
|
||||
+echo 'abcdefghijklmnopqrstuvwxyz' |
|
||||
+tr '[:lower:][:lower:]' '[:upper:]0-9' > out || fail=1
|
||||
+compare out exp || fail=1
|
||||
+
|
||||
+# Validate the alignment of case classes
|
||||
+tr 'A-Z[:lower:]' 'a-y[:upper:]' < /dev/null && fail=1
|
||||
+tr '[:upper:][:lower:]' 'a-y[:upper:]' < /dev/null && fail=1
|
||||
+tr 'A-Y[:lower:]' 'a-z[:upper:]' < /dev/null && fail=1
|
||||
+tr 'A-Z[:lower:]' '[:lower:][:upper:]' < /dev/null && fail=1
|
||||
+tr 'A-Z[:lower:]' '[:lower:]A-Z' < /dev/null && fail=1
|
||||
+tr '[:upper:][:lower:]' 'a-z[:upper:]' < /dev/null || fail=1
|
||||
+tr '[:upper:][:lower:]' '[:upper:]a-z' < /dev/null || fail=1
|
||||
+
|
||||
+# Before coreutils 8.6 the trailing space in string1
|
||||
+# caused the case class in string2 to be extended.
|
||||
+# However that was not portable, dependent on locale
|
||||
+# and in contravention of POSIX.
|
||||
+tr '[:upper:] ' '[:lower:]' < /dev/null 2>out && fail=1
|
||||
+echo 'tr: when translating with string1 longer than string2,
|
||||
+the latter string must not end with a character class' > exp
|
||||
+compare out exp || fail=1
|
||||
+
|
||||
+# Up to coreutils-6.9, tr rejected an unmatched [:lower:] or [:upper:] in SET1.
|
||||
+echo '#$%123abcABC' | tr '[:lower:]' '[.*]' > out || fail=1
|
||||
+echo '#$%123...ABC' > exp
|
||||
+compare out exp || fail=1
|
||||
+echo '#$%123abcABC' | tr '[:upper:]' '[.*]' > out || fail=1
|
||||
+echo '#$%123abc...' > exp
|
||||
+compare out exp || fail=1
|
||||
+
|
||||
+# When doing a case-converting translation with something after the
|
||||
+# [:upper:] and [:lower:] elements, ensure that tr honors the following byte.
|
||||
+echo 'abc.' | tr '[:lower:].' '[:upper:]x' > out || fail=1
|
||||
+echo 'ABCx' > exp
|
||||
+compare out exp || fail=1
|
||||
+
|
||||
+# Before coreutils 8.6 the disparate number of upper and lower
|
||||
+# characters in some locales, triggered abort()s and invalid behavior
|
||||
+export LC_ALL=en_US.ISO-8859-1
|
||||
+
|
||||
+if test "$(locale charmap 2>/dev/null)" = ISO-8859-1; then
|
||||
+ # Up to coreutils-6.9.91, this would fail with the diagnostic:
|
||||
+ # tr: misaligned [:upper:] and/or [:lower:] construct
|
||||
+ # with LC_CTYPE=en_US.ISO-8859-1.
|
||||
+ tr '[:upper:]' '[:lower:]' < /dev/null || fail=1
|
||||
+
|
||||
+ tr '[:upper:] ' '[:lower:]' < /dev/null 2>out && fail=1
|
||||
+ echo 'tr: when translating with string1 longer than string2,
|
||||
+the latter string must not end with a character class' > exp
|
||||
+ compare out exp || fail=1
|
||||
+
|
||||
+ # Ensure when there are a different number of elements
|
||||
+ # in each string, we validate the case mapping correctly
|
||||
+ echo 'abc.xyz' |
|
||||
+ tr 'ab[:lower:]' '0-1[:upper:]' > out || fail=1
|
||||
+ echo 'ABC.XYZ' > exp
|
||||
+ compare out exp || fail=1
|
||||
+
|
||||
+ # Ensure we extend string2 appropriately
|
||||
+ echo 'ABC- XYZ' |
|
||||
+ tr '[:upper:]- ' '[:lower:]_' > out || fail=1
|
||||
+ echo 'abc__xyz' > exp
|
||||
+ compare out exp || fail=1
|
||||
+
|
||||
+ # Ensure the size of the case classes are accounted
|
||||
+ # for as a unit.
|
||||
+ echo 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
|
||||
+ tr '[:upper:]A-B' '[:lower:]0' >out || fail=1
|
||||
+ echo '00cdefghijklmnopqrstuvwxyz' > exp
|
||||
+ compare out exp || fail=1
|
||||
+
|
||||
+ # Ensure the size of the case classes are accounted
|
||||
+ # for as a unit.
|
||||
+ echo 'a' |
|
||||
+ tr -t '[:lower:]a' '[:upper:]0' >out || fail=1
|
||||
+ echo '0' > exp
|
||||
+ compare out exp || fail=1
|
||||
+
|
||||
+ # Ensure the size of the case classes are accounted
|
||||
+ # for as a unit.
|
||||
+ echo 'a' |
|
||||
+ tr -t '[:lower:][:lower:]a' '[:lower:][:upper:]0' >out || fail=1
|
||||
+ echo '0' > exp
|
||||
+ compare out exp || fail=1
|
||||
+fi
|
||||
+
|
||||
+Exit $fail
|
|
@ -1,3 +1,21 @@
|
|||
lib/linebuffer.h | 8 +
|
||||
src/cut.c | 420 ++++++++++++++++++++++++++--
|
||||
src/expand.c | 160 +++++++++++-
|
||||
src/fold.c | 309 +++++++++++++++++++--
|
||||
src/join.c | 345 ++++++++++++++++++++---
|
||||
src/pr.c | 431 ++++++++++++++++++++++++++---
|
||||
src/sort.c | 692 ++++++++++++++++++++++++++++++++++++++++++++--
|
||||
src/unexpand.c | 226 +++++++++++++++-
|
||||
src/uniq.c | 259 +++++++++++++++++-
|
||||
tests/Makefile.am | 5 +
|
||||
tests/misc/cut | 4 +-
|
||||
tests/misc/mb1.I | 4 +
|
||||
tests/misc/mb1.X | 4 +
|
||||
tests/misc/mb2.I | 4 +
|
||||
tests/misc/mb2.X | 4 +
|
||||
tests/misc/sort-mb-tests | 58 ++++
|
||||
16 files changed, 2757 insertions(+), 176 deletions(-)
|
||||
|
||||
diff -urNp coreutils-8.5-orig/lib/linebuffer.h coreutils-8.5/lib/linebuffer.h
|
||||
--- coreutils-8.5-orig/lib/linebuffer.h 2010-04-23 15:44:00.000000000 +0200
|
||||
+++ coreutils-8.5/lib/linebuffer.h 2010-04-26 14:24:33.000000000 +0200
|
||||
|
@ -2433,12 +2451,8 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
#include "system.h"
|
||||
#include "argmatch.h"
|
||||
#include "error.h"
|
||||
@@ -124,14 +133,38 @@ static int decimal_point;
|
||||
/* Thousands separator; if -1, then there isn't one. */
|
||||
static int thousands_sep;
|
||||
@@ -126,12 +135,34 @@ static int thousands_sep;
|
||||
|
||||
+static int force_general_numcompare = 0;
|
||||
+
|
||||
/* Nonzero if the corresponding locales are hard. */
|
||||
static bool hard_LC_COLLATE;
|
||||
-#if HAVE_NL_LANGINFO
|
||||
|
@ -2473,7 +2487,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
/* The kind of blanks for '-b' to skip in various options. */
|
||||
enum blanktype { bl_start, bl_end, bl_both };
|
||||
|
||||
@@ -270,13 +303,11 @@ static bool reverse;
|
||||
@@ -270,13 +301,11 @@ static bool reverse;
|
||||
they were read if all keys compare equal. */
|
||||
static bool stable;
|
||||
|
||||
|
@ -2490,7 +2504,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
|
||||
/* Flag to remove consecutive duplicate lines from the output.
|
||||
Only the last of a sequence of equal lines will be output. */
|
||||
@@ -714,6 +745,44 @@ reap_some (void)
|
||||
@@ -714,6 +743,44 @@ reap_some (void)
|
||||
update_proc (pid);
|
||||
}
|
||||
|
||||
|
@ -2535,7 +2549,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
/* Clean up any remaining temporary files. */
|
||||
|
||||
static void
|
||||
@@ -1158,7 +1227,7 @@ zaptemp (const char *name)
|
||||
@@ -1158,7 +1225,7 @@ zaptemp (const char *name)
|
||||
free (node);
|
||||
}
|
||||
|
||||
|
@ -2544,7 +2558,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
|
||||
static int
|
||||
struct_month_cmp (const void *m1, const void *m2)
|
||||
@@ -1173,7 +1242,7 @@ struct_month_cmp (const void *m1, const
|
||||
@@ -1173,7 +1240,7 @@ struct_month_cmp (const void *m1, const void *m2)
|
||||
/* Initialize the character class tables. */
|
||||
|
||||
static void
|
||||
|
@ -2553,7 +2567,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
{
|
||||
size_t i;
|
||||
|
||||
@@ -1185,7 +1254,7 @@ inittables (void)
|
||||
@@ -1185,7 +1252,7 @@ inittables (void)
|
||||
fold_toupper[i] = toupper (i);
|
||||
}
|
||||
|
||||
|
@ -2562,7 +2576,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
/* If we're not in the "C" locale, read different names for months. */
|
||||
if (hard_LC_TIME)
|
||||
{
|
||||
@@ -1268,6 +1337,64 @@ specify_nmerge (int oi, char c, char con
|
||||
@@ -1268,6 +1335,84 @@ specify_nmerge (int oi, char c, char const *s)
|
||||
xstrtol_fatal (e, oi, c, long_options, s);
|
||||
}
|
||||
|
||||
|
@ -2571,12 +2585,25 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
+inittables_mb (void)
|
||||
+{
|
||||
+ int i, j, k, l;
|
||||
+ char *name, *s;
|
||||
+ char *name, *s, *lc_time, *lc_ctype;
|
||||
+ size_t s_len, mblength;
|
||||
+ char mbc[MB_LEN_MAX];
|
||||
+ wchar_t wc, pwc;
|
||||
+ mbstate_t state_mb, state_wc;
|
||||
+
|
||||
+ lc_time = setlocale (LC_TIME, "");
|
||||
+ if (lc_time)
|
||||
+ lc_time = xstrdup (lc_time);
|
||||
+
|
||||
+ lc_ctype = setlocale (LC_CTYPE, "");
|
||||
+ if (lc_ctype)
|
||||
+ lc_ctype = xstrdup (lc_ctype);
|
||||
+
|
||||
+ if (lc_time && lc_ctype)
|
||||
+ /* temporarily set LC_CTYPE to match LC_TIME, so that we can convert
|
||||
+ * the names of months to upper case */
|
||||
+ setlocale (LC_CTYPE, lc_time);
|
||||
+
|
||||
+ for (i = 0; i < MONTHS_PER_YEAR; i++)
|
||||
+ {
|
||||
+ s = (char *) nl_langinfo (ABMON_1 + i);
|
||||
|
@ -2621,13 +2648,20 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
+ }
|
||||
+ qsort ((void *) monthtab, MONTHS_PER_YEAR,
|
||||
+ sizeof (struct month), struct_month_cmp);
|
||||
+
|
||||
+ if (lc_time && lc_ctype)
|
||||
+ /* restore the original locales */
|
||||
+ setlocale (LC_CTYPE, lc_ctype);
|
||||
+
|
||||
+ free (lc_ctype);
|
||||
+ free (lc_time);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Specify the amount of main memory to use when sorting. */
|
||||
static void
|
||||
specify_sort_size (int oi, char c, char const *s)
|
||||
@@ -1478,7 +1605,7 @@ buffer_linelim (struct buffer const *buf
|
||||
@@ -1478,7 +1623,7 @@ buffer_linelim (struct buffer const *buf)
|
||||
by KEY in LINE. */
|
||||
|
||||
static char *
|
||||
|
@ -2636,7 +2670,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
{
|
||||
char *ptr = line->text, *lim = ptr + line->length - 1;
|
||||
size_t sword = key->sword;
|
||||
@@ -1487,10 +1614,10 @@ begfield (const struct line *line, const
|
||||
@@ -1487,10 +1632,10 @@ begfield (const struct line *line, const struct keyfield *key)
|
||||
/* The leading field separator itself is included in a field when -t
|
||||
is absent. */
|
||||
|
||||
|
@ -2649,7 +2683,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
++ptr;
|
||||
if (ptr < lim)
|
||||
++ptr;
|
||||
@@ -1516,11 +1643,70 @@ begfield (const struct line *line, const
|
||||
@@ -1516,11 +1661,70 @@ begfield (const struct line *line, const struct keyfield *key)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -2721,7 +2755,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
{
|
||||
char *ptr = line->text, *lim = ptr + line->length - 1;
|
||||
size_t eword = key->eword, echar = key->echar;
|
||||
@@ -1535,10 +1721,10 @@ limfield (const struct line *line, const
|
||||
@@ -1535,10 +1739,10 @@ limfield (const struct line *line, const struct keyfield *key)
|
||||
`beginning' is the first character following the delimiting TAB.
|
||||
Otherwise, leave PTR pointing at the first `blank' character after
|
||||
the preceding field. */
|
||||
|
@ -2734,7 +2768,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
++ptr;
|
||||
if (ptr < lim && (eword || echar))
|
||||
++ptr;
|
||||
@@ -1584,10 +1770,10 @@ limfield (const struct line *line, const
|
||||
@@ -1584,10 +1788,10 @@ limfield (const struct line *line, const struct keyfield *key)
|
||||
*/
|
||||
|
||||
/* Make LIM point to the end of (one byte past) the current field. */
|
||||
|
@ -2747,7 +2781,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
if (newlim)
|
||||
lim = newlim;
|
||||
}
|
||||
@@ -1618,6 +1804,113 @@ limfield (const struct line *line, const
|
||||
@@ -1618,6 +1822,113 @@ limfield (const struct line *line, const struct keyfield *key)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -2861,7 +2895,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
/* Fill BUF reading from FP, moving buf->left bytes from the end
|
||||
of buf->buf to the beginning first. If EOF is reached and the
|
||||
file wasn't terminated by a newline, supply one. Set up BUF's line
|
||||
@@ -1700,8 +1993,24 @@ fillbuf (struct buffer *buf, FILE *fp, c
|
||||
@@ -1700,8 +2011,24 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
|
||||
else
|
||||
{
|
||||
if (key->skipsblanks)
|
||||
|
@ -2888,7 +2922,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
line->keybeg = line_start;
|
||||
}
|
||||
}
|
||||
@@ -1739,7 +2048,7 @@ fillbuf (struct buffer *buf, FILE *fp, c
|
||||
@@ -1739,7 +2066,7 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
|
||||
hideously fast. */
|
||||
|
||||
static int
|
||||
|
@ -2897,7 +2931,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
{
|
||||
while (blanks[to_uchar (*a)])
|
||||
a++;
|
||||
@@ -1848,6 +2157,25 @@ human_numcompare (const char *a, const c
|
||||
@@ -1848,6 +2175,25 @@ human_numcompare (const char *a, const char *b, struct keyfield *key)
|
||||
: strnumcmp (a, b, decimal_point, thousands_sep));
|
||||
}
|
||||
|
||||
|
@ -2923,7 +2957,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
static int
|
||||
general_numcompare (const char *sa, const char *sb)
|
||||
{
|
||||
@@ -1881,7 +2209,7 @@ general_numcompare (const char *sa, cons
|
||||
@@ -1881,7 +2227,7 @@ general_numcompare (const char *sa, const char *sb)
|
||||
Return 0 if the name in S is not recognized. */
|
||||
|
||||
static int
|
||||
|
@ -2932,7 +2966,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
{
|
||||
size_t lo = 0;
|
||||
size_t hi = MONTHS_PER_YEAR;
|
||||
@@ -2062,11 +2390,79 @@ compare_version (char *restrict texta, s
|
||||
@@ -2062,11 +2408,80 @@ compare_version (char *restrict texta, size_t lena,
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
@ -2969,7 +3003,8 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
+ memset (&state, '\0', sizeof(mbstate_t));
|
||||
+
|
||||
+ wclength = mbsrtowcs (month_wcs, pp, len + 1, &state);
|
||||
+ assert (wclength != (size_t)-1 && *pp == NULL);
|
||||
+ if (wclength == (size_t)-1 || *pp != NULL)
|
||||
+ error (SORT_FAILURE, 0, _("Invalid multibyte input %s."), quote(s));
|
||||
+
|
||||
+ for (i = 0; i < wclength; i++)
|
||||
+ {
|
||||
|
@ -3013,7 +3048,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
{
|
||||
struct keyfield *key = keylist;
|
||||
|
||||
@@ -2246,6 +2642,179 @@ keycompare (const struct line *a, const
|
||||
@@ -2246,6 +2661,179 @@ keycompare (const struct line *a, const struct line *b)
|
||||
return key->reverse ? -diff : diff;
|
||||
}
|
||||
|
||||
|
@ -3193,7 +3228,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
/* Compare two lines A and B, returning negative, zero, or positive
|
||||
depending on whether A compares less than, equal to, or greater than B. */
|
||||
|
||||
@@ -3244,7 +3813,7 @@ main (int argc, char **argv)
|
||||
@@ -3244,7 +3832,7 @@ main (int argc, char **argv)
|
||||
initialize_exit_failure (SORT_FAILURE);
|
||||
|
||||
hard_LC_COLLATE = hard_locale (LC_COLLATE);
|
||||
|
@ -3202,7 +3237,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
hard_LC_TIME = hard_locale (LC_TIME);
|
||||
#endif
|
||||
|
||||
@@ -3265,6 +3834,27 @@ main (int argc, char **argv)
|
||||
@@ -3265,6 +3853,27 @@ main (int argc, char **argv)
|
||||
thousands_sep = -1;
|
||||
}
|
||||
|
||||
|
@ -3230,7 +3265,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
have_read_stdin = false;
|
||||
inittables ();
|
||||
|
||||
@@ -3536,13 +4126,35 @@ main (int argc, char **argv)
|
||||
@@ -3536,13 +4145,35 @@ main (int argc, char **argv)
|
||||
|
||||
case 't':
|
||||
{
|
||||
|
@ -3270,7 +3305,7 @@ diff -urNp coreutils-8.5-orig/src/sort.c coreutils-8.5/src/sort.c
|
|||
else
|
||||
{
|
||||
/* Provoke with `sort -txx'. Complain about
|
||||
@@ -3553,9 +4165,12 @@ main (int argc, char **argv)
|
||||
@@ -3553,9 +4184,12 @@ main (int argc, char **argv)
|
||||
quote (optarg));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Summary: A set of basic GNU tools commonly used in shell scripts
|
||||
Name: coreutils
|
||||
Version: 8.5
|
||||
Release: 4%{?dist}
|
||||
Release: 7%{?dist}
|
||||
License: GPLv3+
|
||||
Group: System Environment/Base
|
||||
Url: http://www.gnu.org/software/coreutils/
|
||||
|
@ -18,6 +18,10 @@ Source202: coreutils-su-l.pamd
|
|||
Source203: coreutils-runuser-l.pamd
|
||||
|
||||
# From upstream
|
||||
#fix double free error in tac (reported in debian bug #594666)
|
||||
Patch1: coreutils-8.5-tac-doublefree.patch
|
||||
#fix various case conversion issues in tr(#611274)
|
||||
Patch2: coreutils-8.5-trcaseconversion.patch
|
||||
|
||||
# Our patches
|
||||
#general patch to workaround koji build system issues
|
||||
|
@ -62,6 +66,8 @@ Patch912: coreutils-overflow.patch
|
|||
Patch915: coreutils-split-pam.patch
|
||||
#prevent koji build failure with wrong getfacl exit code
|
||||
Patch916: coreutils-getfacl-exit-code.patch
|
||||
#compile su with pie flag
|
||||
Patch917: coreutils-8.4-su-pie.patch
|
||||
|
||||
#SELINUX Patch - implements Redhat changes
|
||||
#(upstream did some SELinux implementation unlike with RedHat patch)
|
||||
|
@ -121,6 +127,8 @@ Libraries for coreutils package.
|
|||
%setup -q
|
||||
|
||||
# From upstream
|
||||
%patch1 -p1 -b .doublefree
|
||||
%patch2 -p1 -b .caseconvert
|
||||
|
||||
# Our patches
|
||||
%patch100 -p1 -b .configure
|
||||
|
@ -146,12 +154,14 @@ Libraries for coreutils package.
|
|||
%patch912 -p1 -b .overflow
|
||||
%patch915 -p1 -b .splitl
|
||||
%patch916 -p1 -b .getfacl-exit-code
|
||||
%patch917 -p1 -b .pie
|
||||
|
||||
#SELinux
|
||||
%patch950 -p1 -b .selinux
|
||||
%patch951 -p1 -b .selinuxman
|
||||
|
||||
chmod a+x tests/misc/sort-mb-tests tests/df/direct
|
||||
chmod a+x tests/misc/tr-case-class
|
||||
|
||||
#fix typos/mistakes in localized documentation(#439410, #440056)
|
||||
find ./po/ -name "*.p*" | xargs \
|
||||
|
@ -176,8 +186,7 @@ automake --copy --add-missing
|
|||
touch man/*.x
|
||||
|
||||
make all %{?_smp_mflags} \
|
||||
%{?!nopam:CPPFLAGS="-DUSE_PAM"} \
|
||||
su_LDFLAGS="-pie %{?!nopam:-lpam -lpam_misc}"
|
||||
%{?!nopam:CPPFLAGS="-DUSE_PAM"}
|
||||
|
||||
# XXX docs should say /var/run/[uw]tmp not /etc/[uw]tmp
|
||||
sed -i -e 's,/etc/utmp,/var/run/utmp,g;s,/etc/wtmp,/var/run/wtmp,g' doc/coreutils.texi
|
||||
|
@ -339,6 +348,23 @@ fi
|
|||
%{_libdir}/coreutils
|
||||
|
||||
%changelog
|
||||
* Wed Nov 03 2010 Kamil Dudka <kdudka@redhat.com> - 8.5-7
|
||||
- prevent sort from assertion failure in case LC_CTYPE does not match LC_TIME
|
||||
(#647938)
|
||||
|
||||
* Fri Oct 01 2010 Ondrej Vasik <ovasik@redhat.com> - 8.5-6
|
||||
- various fixes for case conversion in tr(#611274)
|
||||
- change assertion failure for invalid multibyte input
|
||||
in sort to less confusing error message(#591352)
|
||||
- add RELRO protection to su as well (#630017)
|
||||
|
||||
* Wed Sep 29 2010 jkeating - 8.5-5.1
|
||||
- Rebuilt for gcc bug 634757
|
||||
|
||||
* Tue Sep 07 2010 Ondrej Vasik <ovasik@redhat.com> - 8.5-5
|
||||
- compile su with pie again (#630017)
|
||||
- fix double free abort in tac (#628213)
|
||||
|
||||
* Thu Jul 22 2010 Ondrej Vasik <ovasik@redhat.com> - 8.5-4
|
||||
- Add .ear, .war, .sar , for Java jar-like archives to
|
||||
dircolors (#616497)
|
||||
|
|
Loading…
Reference in New Issue