Problem:
This is a namespace clash with Mozilla browsers within the core Drupal autocomplete.js

Browsers:
FireFox 3.5
SeaMonkey 1.1.17
Galeon 2.04

So far the following name cause logical error during the auto-complete process:

no autocomplete AJAX, no drop-down
constructor

no autocomplete AJAX and [object Object] is shown in the dropdown and prototype is returned when selected

# Some methods inherited from Function.prototype
toSource
toString
valueOf

# All methods / properties inherited from Object.prototype
propertyIsEnumerable
hasOwnProperty
watch
unwatch
__defineGetter__
etc

However, some keywords appear to pass, like some methods / properties inherited from Function.prototype: apply, call, name, caller, length, ...

Note that the problem is significantly less with the latter versions of FF, but I see that there is still some issues.

Solution
Use .each() instead.

Original report:

The "error" is really just ExtJS catching a null reference array key, and populating the autocomplete suggestions with javascript code, please see attachment.
More info on ExtJS: http://www.extjs.com/

How I fixed this:

Line 198-200 of autocomplete.js:
if (!this.input.value.length) {
return false;
}

changed to:
if (!this.input.value.length || matches.length < 1) {
return false;
}

Had Firebug console.log(matches[key]) and see what it returned (when key was null), and it returned javascript from the ext-jquery-adapter.js

Completely baffled, I just reported this as a bug with autocomplete.js because it's not checking that the array is empty first. Maybe this is a problem with ExtJS and not Drupal ;) But hopefully somebody can figure this out.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

GuyPaddock’s picture

Version: 6.17 » 6.16
Status: Needs review » Active
FileSize
1.42 KB

The actual issue is on line 205 -- the foreach loop:

for (key in matches) {
...
}

This type of problem is described in this blog post, but basically the issue is that the auto-complete code uses the array object like an associative array, but that leaves it wide open to iterate over anything in the array namespace, which can be prototype functions, etc. This explains why when there are no results, it will spit-out javascript text, because it's literally iterating over functions in the Array object.

Attached is a fix for this issue, though I'm not necessarily crazy about it only because this doesn't fix the fact that autocomplete.js abuses the properties of the object like it's an associative array.

GuyPaddock’s picture

Title: autocomplete.js doesn't prohibit referencing null array key, causing error » autocomplete.js can iterate over functions in Array objects
Version: 6.16 » 6.17
Status: Active » Needs review
FileSize
1.42 KB

Forgot to set "needs review".

Re-submitted.

Version: 6.16 » 6.17
Status: Active » Needs work

The last submitted patch, 784670_unsafe_array_iteration_fix.patch, failed testing.

GuyPaddock’s picture

Status: Needs work » Needs review
FileSize
1.47 KB

Re-submitting...

Status: Needs review » Needs work

The last submitted patch, 784670_unsafe_array_iteration_fix.patch, failed testing.

Damien Tournoud’s picture

Please use the generic $.each() function here:

$.each(matches, function(key, element) {
  var li = document.createElement('li');
  $(li)
    .html('<div>'+ element +'</div>')
    .mousedown(function () { ac.select(this); })
    .mouseover(function () { ac.highlight(this); })
    .mouseout(function () { ac.unhighlight(this); });
  li.autocompleteValue = key;
  $(ul).append(li);
});
Damien Tournoud’s picture

Version: 6.17 » 7.x-dev

I checked, this is buggy in D7 too. We need to fix it there first.

coolboygfx’s picture

When using autocomplete in Drupal 6.19, when I select a matching word, the text field is populated with the number coresponding with the word found in 'matches' array and not with the selected word as it should be.

If i change line:
     li.autocompleteValue = key;
with:
     li.autocompleteValue = matches[key];
it seems to work fine.

Is this a bug, or am I missing something?

Original Code (in autocomplete.js):

var ul = document.createElement('ul');
var ac = this;
for (key in matches) {
var li = document.createElement('li');
$(li)
.html('

'+ matches[key] +'

')
.mousedown(function () { ac.select(this); })
.mouseover(function () { ac.highlight(this); })
.mouseout(function () { ac.unhighlight(this); });
li.autocompleteValue = key; //------------------------ here is the line (212)---------------
$(ul).append(li);
}

I've also just reported this as a bug with autocomplete feature.

coolboygfx’s picture

FileSize
125.15 KB
coolboygfx’s picture

I found why the text field is populated with the number coresponding with the word found in 'matches' array and not with the selected word. It was my mistake. You can see why here.

arithmetric’s picture

FileSize
735 bytes

Here's a patch that follows Damien's suggestion from #6.

Basically, the change is replacing the use of for() iteration to iterate over the properties of an object with the jQuery $.each() approach.

arithmetric’s picture

Status: Needs work » Needs review

[bumping status]

Agileware’s picture

#175361: autocomplete shows users errors & code was marked as a duplicate of this issue.

For reference, there are patches there with a different approach in #175361-12: autocomplete shows users errors & code.

McChen’s picture

Patch #11 works for me.

arithmetric’s picture

Version: 7.x-dev » 8.x-dev
arithmetric’s picture

Updating patch for Drupal 8.x.

RobLoach’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs backport to D7

I think this applies to Drupal 7 too.

Alan D.’s picture

rfay’s picture

This needs a good issue summary. Thanks.

Alan D.’s picture

From the original queue:

This is a namespace clash with Mozilla browsers within the core Drupal autocomplete.js

Browsers:
FireFox 3.5
SeaMonkey 1.1.17
Galeon 2.04

So far the following name cause logical error during the auto-complete process:

no autocomplete AJAX, no drop-down
constructor

no autocomplete AJAX and [object Object] is shown in the dropdown and prototype is returned when selected

# Some methods inherited from Function.prototype
toSource
toString
valueOf

# All methods / properties inherited from Object.prototype
propertyIsEnumerable
hasOwnProperty
watch
unwatch
__defineGetter__
etc

However, some keywords appear to pass, like some methods / properties inherited from Function.prototype: apply, call, name, caller, length, ...

Note that the problem is significantly less with the latter versions of FF, but I see that there is still some issues.

Alan D.’s picture

In FF8.01, the properties tend to fail to trigger the autocomplete, resulting in nothing happening. Just plug in one of the 9 listed properties into the project autocomplete and you can see this in action :)

catch’s picture

Issue tags: -JavaScript, -autocomplete, -extjs, -ext-jquery-adapter.js, -Needs backport to D7

Status: Reviewed & tested by the community » Needs work
Issue tags: +JavaScript, +autocomplete, +extjs, +ext-jquery-adapter.js, +Needs backport to D7

The last submitted patch, drupal-784670-16-fix_array_iteration.patch, failed testing.

nod_’s picture

Actually $.each() won't fix this, it's a simple for.

It needs to be done manually:

for (key in matches) {
  if (matches.hasOwnProperty(key)) {
    // rest of the code
  }
}

and that should fix the issue.

( edit ) don't forget #1363748: autocomplete.js is using global variable instead of local either.

nod_’s picture

nod_’s picture

This was committed to core through #1420798: autocomplete.js clean up can someone please test?

Alan D.’s picture

Status: Needs review » Closed (duplicate)

2 1/2 years in the queues and it gets committed in a code clean up! (Original issue was recorded Sep 2009.) One word, Awesome!

From a quick search of the net:

Object.hasOwnProperty() Checks whether a property is inherited.
IE 5.5+ (Issues with Form elements 7-, added support for Host objects from 8+)
Mozilla 1.0+
Netscape 6.0+
Opera 7.0+
Safari (?)2.0+

And this is used internally in many libraries, so it looks fine as far as I can see :)

Marking duplicate as the other thread has the commit and that appears to have the carrot needed to make progress on this matter.

ksenzee’s picture

I don't know what the status of either of these issues is, or whether it's wise to backport a cleanup patch or not. I'm attaching a simple hasOwnProperty fix for D6, that fixes the bug in this issue.

psynaptic’s picture

#28 Looks good.

hefox’s picture

The above patch also is looking good for 6.x... may be worth re-opening this?

hefox’s picture

Issue summary: View changes

trying to write an issue summary