If a user registers a new account called "0" then lots of unexpected things happen. This is because:

if ($user->name)

will evaluate to FALSE whenever it is used. See screenshot.

Comments

lyricnz’s picture

Bug not present in D7 - validate shows "You must enter a username."

damien tournoud’s picture

Version: 6.x-dev » 7.x-dev
lyricnz’s picture

Version: 7.x-dev » 6.x-dev

Bug not present in D7

lyricnz’s picture

Status: Active » Needs review
StatusFileSize
new574 bytes

Changed user_validate_name() to match D7.

jbrown’s picture

Status: Needs review » Needs work

D7 user_validate_name() is wrong.

0 should be a valid user name.

lyricnz’s picture

Status: Needs work » Needs review

It looks like the D6 maintainer deliberately made this change when he committed a cleanup to this code in http://drupal.org/node/266488#comment-2985980

So there's either:

1) A bug in D6 that allows "0" as a username, but doesn't quite support this properly (see screenshot).

2) A bug in D7 that doesn't allow "0" as a username (while D6 does). Actual support for that is not tested.

3) An upgrade problem if the validation in D7 is more strict than D6 (user "0")

Either way, contributed modules are known to make this same mistake "if ($user->name)". I vote for not allowing "0" in either version - this is no more arbitrary than not allowing leading/trailing spaces, double spaces within strings, or any of the more exotic characters.

lyricnz’s picture

Status: Needs review » Needs work

Oops - crosspost.
@jbrown: so you are suggesting there is a bug in D6 (screenshot), and in D7 (not supporting "0"), and in contributed modules that use "if ($user->name)"?

jbrown’s picture

Yes #7 is exactly what I am suggesting.

form.inc checks for (strlen(trim($elements['#value'])) != 0) for required fields.

I don't know why the user code doesn't just leave it up to the forms layer to determine if it has been entered.

Code that needs to determine if an account is anonymous should examine uid, not name.

"0" being considered as an empty string is one of the reasons why people think PHP is a really crap language.

jensimmons’s picture

It makes sense to me to not allow people to use the username "0". I can't see a compelling reason to allow it. It seems like a hacker or troll thing to do. Normal use of Drupal usernames doesn't need this ability.

That said, I don't have my head wrapped around the backend implications of whatever choice.

lyricnz’s picture

Status: Needs work » Needs review
StatusFileSize
new4.73 KB

Okay, I've asked around, and the general consensus seems to be that "0" should be a valid username. That being the case, here's a patch against D7 that fixes some bugs caused by user "0".

- format_username() showing "Anonymous" instead of "0". This shows up on the user-list, for example.

- page title on the user page for "0" not showing correctly

- menu title (next to tabs) on the user page for "0" not showing correctly

- various bugs with page titles of "0", in theming

Of course, this requires the patch at http://drupal.org/node/266488#comment-3171358 to be applied before you can create such a user :)

chx’s picture

Version: 6.x-dev » 7.x-dev
Status: Needs review » Needs work

Presuming $account->name or anything to be a string is a very dangerous assumption especially when dealing with zeroes. 0 == '', 0 == '0' and only '0' != ''. Use !== everywhere. It's faster to boot and leaves no doubts.

lyricnz’s picture

Status: Needs work » Needs review
StatusFileSize
new4.74 KB

Thanks

rfay’s picture

Let's not spill too much blood on this one. It's not important in the big picture and it's worth fixing.

I don't object to this patch, but it doesn't solve all the contrib uses of the same pattern that are out there. There's no reason to allow '0' as a username, and disallowing it prevents all those uses from being problematic.

jbrown’s picture

StatusFileSize
new7.2 KB

format_username()'s technique of checking the username to determine if an account is a guest account is totally wrong. template_preprocess_username() does it correctly: checking the uid.

Okay - this snippet:

$string = '0';

if ($string) {
  return TRUE;
}

doesn't return TRUE!

Assuming that $string is actually a string, the correct way to test that it is empty is

if ($string == '')

To test if it is not empty:

if ($string != '')

A more elaborate test like strlen(trim($string)) == 0) could be used that would handle integer variables, but would be impracticable in theme templates and is unnecessary.

It seems that there are lots of places in core where empty strings are not being correctly tested for.

The attached patch builds on #12, fixing use of $title in bartik and fixing format_username().

jbrown’s picture

Title: Creating a user called "0" has unexpected effects » Robustly determine when strings are empty

Status: Needs review » Needs work

The last submitted patch, check_empty_string.patch, failed testing.

jbrown’s picture

Status: Needs work » Needs review
StatusFileSize
new7.2 KB
lyricnz’s picture

Status: Needs review » Reviewed & tested by the community

Looks good, passes tests - allows account name of "0" without bad behavior (if this is decided to be disallowed, this code is still fine)

chx’s picture

Status: Reviewed & tested by the community » Needs work

Hrm, #11 was too long ago. Then let me repeat: for readability and speed (and disambiguity) !== is much better than !=.

jbrown’s picture

Yes, $variable !== '' will return FALSE if $variable is not a string.

I think this form should always be used if the assumption is that $variable should be a string.

sun’s picture

Agreed with chx here, otherwise looks good.

jbrown’s picture

Just browsing through Seven and Bartik, there are dozens of examples of

<?php if ($variable): ?>

where it should be

<?php if ($variable !== ''): ?>

Should this be standardized and fixed?

#871160: Define programming best practices for determining if a string is empty

chx’s picture

Yes, yes, yes! It should definitely be standardized and fixed. I called for that at my Paris talk about how broken == is.

lyricnz’s picture

Agree. Please let's fix D7 before release - this issue causes a few silly impacts, like mishandling users called "0" etc.

Status: Needs work » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.