bug-m4
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

m4 and signed char bug


From: Kent Boortz
Subject: m4 and signed char bug
Date: 20 Feb 2003 22:50:26 +0100
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7

I got segmentation violation using m4 1.4 on Tru64 alpha. The input
contains a macro definition with a numeric variable immediately
followed by a character > 127, in my case some code in my aclocal.m4

  AC_DEFUN(ERL_TRY_LINK_JAVA,
  [java_link='$JAVAC conftest.java 1>&AC_FD_CC'
  changequote(«, »)dnl
  cat > conftest.java <<EOF
  «$1»
  class conftest { public static void main(String[] args) {
     «$2»
     ; return; }}
  EOF
  .
  .

The machine is

  % uname -a
  OSF1 thorin V5.1 1885 alpha
  % sizer -v
  Compaq Tru64 UNIX V5.1A (Rev. 1885); Mon Oct  1 16:20:40 CEST 2001

On this machine 'char' is signed. In the function expand_user_macro()
the code

            {
              for (i = 0; isdigit (*text); text++)
                i = i*10 + (*text - '0');
            }

will break if the character following the digits is a character number
> 127. The character number sent to isdigit() will be negative. isdigit()
is implemented as a macro that index into an array and a negative
index into this array will read random data.

I can see a number of possible solutions, maybe one of

  - Use unsigned char for all pointerns and variables that handle
    input and output strings.

  - Always cast a 'char' argument to is*() functions with
    (unsigned char).

  - Change "configure.in" to set '-funsigned-char' for platforms where
    'char' is signed (it is a bit hard to write a configure test to
    test if isdigit() index above the array). The disadvantage with
    this solution is that there may be system header files that assume
    that 'char' is signed. I tried

      % CFLAGS="-g -O2 -funsigned-char" ./configure

    and the resulting m4 seem to work for my input data.

  - Replace isdigit() and other macros with your own implementations.

I don't know if the is*() functions fail to check if the input is
negative on other platforms. On OSF1 it is documented to work this way

  PARAMETERS

  c         Specifies the character to be tested. In all cases, this parame-
            ter is an  int data type, whose value must be representable as an
            unsigned char or must equal the value of the macro EOF (defined
            in the stdio.h include file). When this parameter has a value
            that cannot be represented as an unsigned char or EOF, the result
            is undefined.

kent




reply via email to

[Prev in Thread] Current Thread [Next in Thread]