dash printf builtin does not honor \xNN to print hexadecimal

Bug #1499473 reported by Zakhar
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
dash (Ubuntu)
New
Undecided
Unassigned

Bug Description

VERSION AND CONTEXT
===================

$ uname -a; lsb_release -a; dash --version; dpkg -s dash
Linux alain-Desktop 3.13.0-63-generic #103-Ubuntu SMP Fri Aug 14 21:42:59 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.3 LTS
Release: 14.04
Codename: trusty

Package: dash
Essential: yes
Status: install ok installed
Priority: required
Section: shells
Installed-Size: 228
Maintainer: Ubuntu Developers <email address hidden>
Architecture: amd64
Version: 0.5.7-4ubuntu1
Depends: debianutils (>= 2.15), dpkg (>= 1.15.0)
Pre-Depends: libc6 (>= 2.14)
Description: POSIX-compliant shell
 The Debian Almquist Shell (dash) is a POSIX-compliant shell derived
 from ash.
 .
 Since it executes scripts faster than bash, and has fewer library
 dependencies (making it more robust against software or hardware
 failures), it is used as the default system shell on Debian systems.
Homepage: http://gondor.apana.org.au/~herbert/dash/
Original-Maintainer: Gerrit Pape <email address hidden>

BUG DESCRIPTION AND HOW TO REPRODUCE
====================================
Pretty well all is in the title!

Try this in a terminal:

$ bash -c 'printf "\x41\n"'; dash -c 'printf "\x41\n"'; $(which printf) '\x41\n'
A
\x41
A

In case you suspect that comes from expansion in the terminal, you can do the same under dash (type dash in the terminal and do the same line). The result is identical.

Same thing if you have a script:

#! /bin/dash

printf '\x41\n'
printf "\x41\n" # We do both quotes and double quotes in case there is an escaping issue!

This script will display:
\x41
\x41

WHAT IS EXPECTED:
================
Of course what is expected is that dash would display, same as bash and GNU printf:
A

That is what is described in all printf's documentations I could ever read, starting from the ancestor:

#include <stdio.h>

int main(){
   printf("\x41\n");
}

Name this file /tmp/test.c, compile it with gcc /tmp/test.c -o /tmp/test
Then run /tmp/test
You will obviously get:
A

SUMMARY:
========
Testing various printfs with the string: "\x41\n"

Produces the expected output (capital letter A followed by line feed) with:
- the C printf
- the bash builtin
- the GNU printf (in /usr/bin)

Produces an un-escaped output with dash!

I am still searching for dash documentation of the builtin printf, but I seriously doubt such an output for printing '\x41' is even POSIX compliant.

INTERSTING NOTE:
===============
We could suspect there would be the same issue when converting numbers from octal... but no, all is fine with octal!

$ bash -c 'printf "\101\n"'; dash -c 'printf "\101\n"'; $(which printf) '\101\n'
A
A
A

In octal, be it bash, dash or the GNU printf all outputs are identical.

In any case someone might consider "it is not a bug, it is a feature" to NOT honour escaping of hexadecimal and honour the octal escaping we can say at least that this "feature" is a lack of consistency in converting numbers to chars with dash!

INTERESTING NOTE2:
=================
I read from the description of dash on the launchpad: (...) 'dash' which is the Debian Almquist Shell (dash) is a POSIX-compliant shell derived from ash.

Well, I did the same test on my (not Ubuntu-related) Synology that is precisely running ash embedded in busybox (not bash, not dash) and doing

printf '\x41\n'

Produces the expected output: A + LF

[Exact version of this 'ash': BusyBox v1.16.1 (2014-02-11 20:12:01 CST) built-in shell (ash) ]

So there might have been some distortion in the derivation from ash!

Revision history for this message
Zakhar (alainb06) wrote :

Well, I made some more research: I think this can be closed as

WON'T FIX

This seem to be a feature (not a bug) to comply exactly to POSIX, **nothing more**.

Here is the related POSIX documentation:
http://www.unix.com/man-page/POSIX/1posix/printf/

It specifies octal escaping, and it also explains that Hexadecimal escaping can be ambiguous (the explanation is far fetched!)

So ash might have added the \x but dash removed it (probably) to be strictly POSIX to the minimum.

Also, we don't have \u or \U escaping for Unicode.

If you need \x, \u or \U, the workaround is to use the GNU printf instead of the builtin.

Sorry for the inconvenience;

Revision history for this message
Zakhar (alainb06) wrote :

NOTE: can someone move the status to "Won't Fix" please, it is not available to "regular users"!

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.