tags:

views:

211

answers:

4

http://dspace.dial.pipex.com/town/green/gfd34/art/bloopers.html

The first one seems simple;

return strcpy(malloc(strlen(s)), s);

malloc could return null, and strcpy could try to copy data to memory address 0. Or s could be a pointer to a string (rather than an array), and malloc would only allocate enough space for a pointer, and would try and copy a string into it. (I think).

What about the second one though?

What a shame that he didn't cast ch to unsigned char when he wrote ch = toupper(ch);

Why should you cast ch to unsigned char if you write ch = toUpper(ch);?

+1  A: 

The toupper() function expects its input to be an integer in the range of unsigned char (0 - 255), while in some cases a char variable can be in the range of a signed char (-128 - 127).

Zed
+1  A: 

The toupper function expects the argument to be repressentable as an unsigned char or the value EOF. A signed char above 127 would be treated as if it were a negative number if you did not cast it to unsigned char since the argument is an int.

Judge Maygarden
+3  A: 

The toupper function (with a lower case U) takes either the value of an unsigned char or EOF. If char is signed, passing a char to toupper() without converting it to an unsigned char first can pass other values with undefined behaviour. The implementation of toupper often look like this:

int toupper(int c)
{
   return touppermap[c+1];
}

so the problem here is real. (This implementation assumes EOF is -1, which you can't formally do but nothing prevent the implementation to be knowledgeable about its own characteristics).

AProgrammer
I think that's an incorrect representation of the toupper() function. It's probably implemented by switching 6th bit of. 'a' ^ 0x20 == 'A', as is true for all alphabetic characters in ascii.
Emil H
(The issue is real, though. No argument there.)
Emil H
Do you know of any compilers where this actually happens? GCC seems to handle the full range of an `int`.
Judge Maygarden
Judge Maygarden
Emil H: You need something more than just switching the sixth bit off, since that would (for example) convert ` to @!
Thomas Padron-McCarthy
AProgrammer
Masking with 0xFF will have a problem, without going to nine bits characters. '\0xFF' will have the same mapping as EOF. In a latin-1 locale for instance, ÿ will be transformed to EOF, even if char is unsigned. In an implementation where char is signed and EOF -1, it isn't possible for the implementation not to confuse (char)-1 and EOF if the caller doesn't cast a char argument to unsigned char. Note that you don't need to cast an int which stores the result of getc() but that if you store the result of getc() in a char, you can't detect EOF reliably.
AProgrammer
I stand corrected. :) +1 for really knowing what you're talking about.
Emil H
@Emil, I've spend far too much time for my taste tracking bugs due to the signedness or not of char between implementations :-(
AProgrammer
@Judge: it doesn't matter what's a better or a worse implementation. This is a valid implementation, and programmers aren't allowed to assume that the implementation will do extra work to correct their errors.
Steve Jessop
+5  A: 

The first one seems simple; malloc could return null, and strcpy could try to copy data to memory address 0. Or s could be a pointer to a string (rather than an array), and malloc would only allocate enough space for a pointer, and would try and copy a string into it. (I think).

Simple enough, right? You missed the most obvious thing wrong with this: you are not allocating enough space. strcpy() copies the string plus the terminating null byte, so the destination buffer must be size at least 1 bigger than the length of the string.

newacct
actually, if `s` was a stack-allocated array containing a string, it would already contain a null byte. that byte would be considered by the `sizeof()` operator (since you're taking the size of the entire array, not calling `strlen()`) and `malloc` would allocate enough space for `s`. If it was a stack-allocated array.
Carson Myers
@Carson: I think you missed newacct's point... In both the page you link to and your post the problem is exactly what newacct explains. Because you are mallocing strlen() number of characters and then copying strlen()+1 characters you are going out of bounds. Stack allocation and sizeof is not part of the picture and doesn't really matter.
Fredrik
you're right, I forgot that strlen() didn't count the NULL byte but strcpy() would copy it. My bad (I usually write my own strcpy and strlen anyways) -- at least I caught another one, though! (Sorry this is old, I edited the question so I could remove my downvote)
Carson Myers