Bug 108521 - [util-linux] column -s X -t fails when there are colour escapes before X
Summary: [util-linux] column -s X -t fails when there are colour escapes before X
Status: NEW
Alias: None
Product: Tools
Classification: Unclassified
Component: Other (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Tools.Other
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-11-27 00:08 UTC by Simon Kohlmeyer
Modified: 2017-03-12 10:21 UTC (History)
2 users (show)

See Also:
Kernel Version: 4.2.5
Subsystem:
Regression: No
Bisected commit-id:


Attachments
Patch that fixes the issue with HAVE_WIDECHAR (3.50 KB, patch)
2015-11-27 02:39 UTC, Simon Kohlmeyer
Details | Diff

Description Simon Kohlmeyer 2015-11-27 00:08:51 UTC
To Reproduce:

`
test='\033[33mb\033[mXFoo\n\033[33mbar\033[mXFoo'
echo -e $test
echo '=>'
echo -e $test | column -s X -t
`

Expected output (which is produced with test='bXFoo\nbarXFoo'):
bXFoo
barXFoo
=>
b    Foo
bar  Foo

Actual output:
bXFoo
barXFoo
=>
b   Foo
bar   Foo

I'm not quite sure how the escapes should be correctly handled. Colours and other formatting should obviously be stripped, but other escapes could necessitate other handling.
Comment 1 Simon Kohlmeyer 2015-11-27 00:27:14 UTC
The column from bsdmainutils available in debian does not have this problem. I'm on arch using util-linux 2.27.
Comment 2 Simon Kohlmeyer 2015-11-27 00:45:41 UTC
Quote from man wcswidth (which is used in column):

The  wcswidth()  function  returns the number of columns needed to represent the wide-character string pointed to by s, but at most n wide characters.  If a nonprintable wide character occurs among these characters, -1 is returned.

bsdmainutil uses
/* Like wcswidth(), but ignores non-printing characters. */
int
width(const wchar_t *wcs)
{
	int w, cw;

	for (w = 0; *wcs != L'\0'; wcs++)
		if ((cw = wcwidth(*wcs)) > 0)
			w += cw;
	return (w);
}
Comment 3 Simon Kohlmeyer 2015-11-27 02:39:23 UTC
Created attachment 195581 [details]
Patch that fixes the issue with HAVE_WIDECHAR

Without HAVE_WIDECHAR, -s and -t don't seem to work at all:

echo 'bXfoo\nbarXfoo' | ./column -s X -t
bXfoo
barXfoo

(I changed #define HAVE_WIDECHAR 1 to #undef HAVE_WIDECHAR in config.h. I'm no autotools expert, please advise if this doesn't do the trick)

I tried to make the new function work with and without HAVE_WIDECHAR defined and could confirm that it correctly strips out control sequences in both cases.
Comment 4 Simon Kohlmeyer 2015-12-03 13:57:53 UTC
Looks like my patch doesn't work after all. Sorry.

I've switched over to another workaround in the meantime
Comment 5 Fernando Castillo 2016-05-01 15:03:57 UTC
This bug has been fixed in util-linux 2.28 with the following commit:

commit 683ddbd5c4a7c28db878bd5b2387c7cff2504967
Author: Karel Zak <kzak@redhat.com>
Date:   Wed Jan 13 10:08:39 2016 +0100

    column: ignore non-printable chars

    echo -e '\033[33mb\033[mXFoo\n\033[33mbar\033[mXFoo' | column -s X -t

    old version:

        b   Foo
        bar   Foo

    fixed version:

        b    Foo
        bar  Foo

    References: https://github.com/karelzak/util-linux/issues/252

Note You need to log in before you can comment on or make changes to this bug.