iosart blog » Bugs https://blog.iosart.com web ~ music ~ photography ~ life Sat, 17 Nov 2012 06:59:11 +0000 en-US hourly 1 http://wordpress.org/?v=4.2.18 Recent Mozilla Adventures https://blog.iosart.com/2005/04/28/recent-mozilla-adventures/ https://blog.iosart.com/2005/04/28/recent-mozilla-adventures/#comments Thu, 28 Apr 2005 20:55:05 +0000 http://www.iosart.com/blog/archives/2005/04/28/40/ Several interesting issues I’ve encountered while developing the PlainOldFavorties extension:

  • Mozilla cannot correctly handle filenames that contain Unicode characters (on Windows). See bug 162361 for more details.

    Unicode issues seem to haunt many products and frameworks, and as I found out, Mozilla is no exception. If this is issue is important to you (and if you are located in a non-English environment, it should be), please vote for this bug, provide some useful feedback or even consider contributing some code for solving the problem.
  • I found no way to sort an XPCOM array (nsIMutableArray) from JavaScript. I’ve solved this issue by first creating a regular JavaScript array (Array class). Once I’ve added all the wanted elements to the JavaScript array, I called its ‘sort’ method and then added the elements in their sorted order to the nsIMutableArray. If anyone knows a better way to do this, please let me know. Otherwise, I believe that the interface should be expanded to allow this important functionality.
]]>
https://blog.iosart.com/2005/04/28/recent-mozilla-adventures/feed/ 1
How to run a clean-up script when your extension is uninstalled https://blog.iosart.com/2004/08/20/how-to-run-a-clean-up-script-when-your-extension-is-uninstalled/ https://blog.iosart.com/2004/08/20/how-to-run-a-clean-up-script-when-your-extension-is-uninstalled/#comments Fri, 20 Aug 2004 14:28:49 +0000 http://www.iosart.com/blog/archives/2004/08/20/13/ Right now there is no support in the Firefox Extension Manager for running a script when the extension is uninstalled. Such script might be useful if your extension needs to perform some clean up, like removing some temporary files or registry entries.

I’ve managed to find a work around for this:

  1. Install an unload event handler in your overlay Javascript:

    addEventListener("unload", overlayUnloaded, false);

    The overlayUnloaded function will be called each time the user closes the browser window.
  2. In the overlayUnloaded function, ask the extension manager (nsIExtensionManager) whether your extension is in toBeUninstalled state.
  3. If so, the user has uninstalled your extension – go ahead and run your clean-up code.

A related technique is determining that your extension has been updated, and something went wrong.

I can provide the complete source code (in Javascript) for this technique on request.

]]>
https://blog.iosart.com/2004/08/20/how-to-run-a-clean-up-script-when-your-extension-is-uninstalled/feed/ 8
A multiplatform extension for Firefox https://blog.iosart.com/2004/08/13/a-multiplatform-extension-for-firefox/ https://blog.iosart.com/2004/08/13/a-multiplatform-extension-for-firefox/#comments Fri, 13 Aug 2004 17:07:27 +0000 http://www.iosart.com/blog/archives/2004/08/13/11/ Update: Bug 253742 is very close to being fixed, so the workarounds in this post will no longer be needed. Thanks to the Mozilla developers for making the platform even better.

Every Firefox extension consists of several parts. It often has a UI part, typically written in XUL and some scripts typically written in Javascript. More advanced extensions have compiled XPCOM components in form of .dll or .so files.

While the XUL and the Javascript parts can often be used on all platforms (Windows, Linux etc.) without modification, the XPCOM components need to be platform specific (for obvious reasons).

I wanted to have a single extension package (XPI), which included the XPCOM components for all the platforms. When the extension is installed, it should detect the user platform and load only the appropriate components.

The first thing I noticed is that the extension manager mechanism doesn’t allow conditional installations (install different components depending on user’s platform).

Next, I tried the following reasoning: package both .dll and .so files with the extension. Firefox on Windows will load only the .dll files while ignoring the .so files, and on Linux only the .so files, while ignoring the .dll files. It was only logical to me that the Windows version of Firefox will not try to load the .so files.

It didn’t work. Windows Firefox did try to load the .so file and popped up and ugly message box saying something about wrong file format. Looking through Mozilla source code, I saw that there is a list of all the dynamic libraries extensions (.dll, .so etc.) and Mozilla will try to load all the file types on all the platforms.

After posting a question on the mozillazine.org forums, I got an answer saying that I should provide several different packages for the different platforms. I wasn’t ready to go that way. Managing several packages, when all that is different between them is a single file seemed unreasonable.

So I came up with a work-around. I had only Windows and Linux versions, but the technique can be extended further to support more platforms. Here it is:

  1. Package the Windows version of the component as MyComponent.dll
  2. Package the Linux version of the component as MyComponent.dll.linux
  3. Windows will load the .dll file while ignoring the .dll.linux file (because its extension is not a valid dynamic library extension). Nothing else should be done here.
  4. On Linux – the first time the extension is loaded, it will try to load MyComponent.dll file and fail (because the file is a Windows DLL). It will fail gracefully, without popping up any message boxes.
  5. During the startup of my extension I check whether the user platform is Linux and if MyComponent.dll.linux file exists.
  6. If so, this means that this is the first run. The script moves (renames) MyComponent.dll.linux to MyComponent.dll, removes the components registry files, compreg.dat and xpti.dat, so they are rebuilt the next time Firefox is started
    and inform the user that an additional restart is needed.
  7. When the browser is restarted, the MyComponent.dll is loaded successfully (because it is now a valid .so file) and the registry files are rebuilt to reflect its contents.
  8. The extension is now fully functional.

One little question needs to be answered – why do I rename MyComponent.dll.linux to MyComponent.dll and not to something more Linux-like as MyComponent.so.
The answer is – uninstall. If I created a new file named MyComponent.so, when my extension got uninstalled the file wouldn’t have been deleted, because it was never installed. Moving MyComponent.dll.linux to MyComponent.dll leaves all the files with exactly the same names, so when uninstall comes, they are removed.

I can provide the complete source code (in Javascript) for this technique on request.

]]>
https://blog.iosart.com/2004/08/13/a-multiplatform-extension-for-firefox/feed/ 7
Firefox extension update failure https://blog.iosart.com/2004/08/13/firefox-extension-update-failure/ https://blog.iosart.com/2004/08/13/firefox-extension-update-failure/#comments Fri, 13 Aug 2004 14:24:11 +0000 http://www.iosart.com/blog/archives/2004/08/13/12/ Update: This issue (bug 252543) has been solved in Mozilla, so the workaround is no longer needed.

I have written a Firefox extension which uses an XPCOM component. When the extension is installed and the user will try to install a newer version of the extension, the installation fails.

The reason for the failure is that the old version of the extension is already loaded when the new version installation is attempted. The XPCOM component DLL is in use and it cannot be overwritten with the new version of the DLL.

So, what happens is that the old version of the extension remains installed and the Extension Manager says “the extension will be installed the next time you start Firefox” no matter how many time you restart the browser.

Making the users uninstall the old version of the extension before installing the new one solves the problem, but it is not a very user friendly way of solving this.

My solution:

  1. Detect the situation. To detect the situation, my extension queries the Extension Manager on every startup. If it detects that there is a version of the same extension (self) with a status “toBeInstalled”, it probably means that the user has installed a new version of the extension and the installation failed. Otherwise the status would have been “installed”.
    If this situation is detected, I move (rename) the component DLL MyComponent.dll to MyComponent.dll.uninstalled. This will succeed, because you can rename a DLL when it is in use, even though you cannot remove or overwrite it.
  2. I then notify the user that an additional restart of the browser is needed.
  3. When the browser is started for the next time, the installation will succeed because the file
    MyComponent.dll is no longer in use.

One little point that shouldn’t be overlooked – we have created a new file, MyComponent.dll.uninstalled, in the components directory. This file will not get deleted when the extension is uninstalled, because we never installed it. To solve this, I have packaged an empty MyComponent.dll.uninstalled file with the extension. Because this file has and “uninstalled” extension, it is ignored by everyone. When it is time to uninstall the extension the file is removed along with all the other extension files.

I can provide the complete source code (in Javascript) for this technique on request.

]]>
https://blog.iosart.com/2004/08/13/firefox-extension-update-failure/feed/ 2
Internet Explorer Filter Quirks https://blog.iosart.com/2004/06/30/internet-explorer-filter-quirks/ https://blog.iosart.com/2004/06/30/internet-explorer-filter-quirks/#comments Wed, 30 Jun 2004 12:43:13 +0000 http://www.iosart.com/blog/archives/2004/06/30/10/ My online photo galleries show thumbnails of the photographs for every folder. Sometimes after reloading a gallery page some of the off-screen thumbnails weren’t rendered – only a gray rectangle appeared instead of the image. Hovering over the thumbnail revealed the correct image.

The thumbnails have a filter:progid:DXImageTransform.Microsoft.Shadow(...) CSS style applied to them which means that they have a nice shadow. Removing this style solved the problem, but obviously the gallery looked less nice.

Pim Rijpsma explained to me that the problem is caused by a buggy DirectX implementation – Internet Explorer uses DirectX to apply the effect and for off-screen images the image sometimes “gets stuck” in some internal buffer. Hovering over the image creates another request and the image is finally shown.

Obviously, I have no control over people’s DirectX version. Hovering over the problematic images makes things right, so why not simulate this hovering over all the thumbnails after the page loads? I ended up using the following code:


<!--[if gte IE 5.5]>
<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript">
function RefreshThumbnails() {
  var aReturn=document.body.getElementsByTagName("A");
  for(i = 0; i < aReturn.length; i++) {
    if (aReturn[i].currentStyle.filter != '') {
	 aReturn[i].setActive();
    }
  }
  window.status = 'Done';
}

window.onload = RefreshThumbnails;
</SCRIPT>
<![endif]-->

Basically, the code checks if the browser is IE5.5 or newer. If so –
go over all the Anchors which have filters and activate them (which is apparently similar to hovering).

The code is executed on page load. It solves the problem quite nicely.

]]>
https://blog.iosart.com/2004/06/30/internet-explorer-filter-quirks/feed/ 0
Crazy layout dance https://blog.iosart.com/2004/05/27/crazy-layout-dance/ https://blog.iosart.com/2004/05/27/crazy-layout-dance/#comments Thu, 27 May 2004 20:15:00 +0000 http://www.iosart.com/blog/archives/2004/05/27/9/ I have noticed that several HTML pages change their layout wildly while loading in the browser. Apparently, this behavior was caused by images at the top of the problematic pages. The image was added using JavaScript: document.writeln("<IMG SRC=...>");.

Internet Explorer didn’t like that – it had problems determining the correct page layout while loading, so it used a preliminary layout first and then the final layout. This switch in layout in the middle of loading was the reason for the annoying “jumps”.

I switched to server side include techniques (mod_include and PHP “virtual“) so the browser gets the page as the final HTML – image and all.

]]>
https://blog.iosart.com/2004/05/27/crazy-layout-dance/feed/ 0
Fooling Apache https://blog.iosart.com/2004/05/26/fooling-apache/ https://blog.iosart.com/2004/05/26/fooling-apache/#comments Wed, 26 May 2004 23:37:04 +0000 http://www.iosart.com/blog/archives/2004/05/26/8/ Tweaking with the Apache configuration, I encountered some pretty interesting problems.

I used mod_rewrite to serve different content based on the HTTP request. Basically, what I was trying to do is this: there are two domains, “one.com” and “two.com” both pointing to the same server. If the user used the first domain name in the address, serve “Page A”, else serve “Page B”. This can be accomplished quite easily by using the RewriteCond %{HTTP_HOST} ^one.com$ directive.

I used the above technique and all was well, until I noticed that the images served by the one.com domain are not being cached by the browser! To find out what was going on I used wget with the “-S” option to see the full header returned by the server. The server was returning a header which included a “Vary: Host” field, which means that the server didn’t serve a regular static page, but its reply depends on the “Host” field in the HTTP request. Browsers interpret this as “the content returned is dynamic, don’t cache it.

I needed to get rid of the “Vary” header. One option was to use the Header unset Vary directive, but that requires mod_header module, which is unfortunately isn’t included in my server. Another option is to use the SetEnv force-no-vary directive. This tells the server not to return the “Vary” field.

It seams like problem solved… Not exactly. SetEnv force-no-vary along with suppressing the “Vary” header, forces the response to be HTTP/1.0. Why is this a problem? When serving HTTP/1.0, some advanced features of HTTP/1.1 aren’t used. One of these features is “Keep-Alive”. This feature can increase the loading time of the page by up to 50% by using the same connection for more than one request. Turn this off and it takes much longer to load pages with many images – and this incidentally was exactly the type of pages I was serving!

So “SetEnv force-no-vary” is out too. What can be done to make the server stop sending the damn “Vary” header? I needed a way to fool the server so it doesn’t notice I’m checking the Host header field. A simple solution then came too mind – what if I save the HTTP_HOST value in an environment variable and use this variable in the condition directive. The server won’t have any way of knowing that this variable actually contains the HTTP_HOST and stop sending the “Vary” field. I used the following code:


RewriteRule .*  - [E=MY_HTTP_HOST:%{HTTP_HOST}]
RewriteCond %{ENV:MY_HTTP_HOST} ^one.com$

The first line sets a new environment variable “MY_HTTP_HOST” and initializes it with HTTP_HOST. The second line is the condition and it looks to the server as if I check a regular environment variable. This finally solved the problem.

]]>
https://blog.iosart.com/2004/05/26/fooling-apache/feed/ 5
IE6 CSS bug https://blog.iosart.com/2004/05/26/ie6-css-bug/ https://blog.iosart.com/2004/05/26/ie6-css-bug/#comments Wed, 26 May 2004 23:33:42 +0000 http://www.iosart.com/blog/archives/2004/05/26/7/ DHTML – using a floated DIV followed by a <DIV STYLE="clear:both;"> causes some strange behavior in IE6 – a large portion of the page disappears and reappears randomly after refresh and/or mouse hover.

What was happening is that the above configuration brought out a bug in IE6 and it drew the (white) background OVER the text in the DIV. Removing the background: white; from the style sheet solved the problem, but I really needed the background to be white. Putting the same background setting on the parent container solved the problem.

]]>
https://blog.iosart.com/2004/05/26/ie6-css-bug/feed/ 0
MFC blues https://blog.iosart.com/2004/05/26/mfc-blues/ https://blog.iosart.com/2004/05/26/mfc-blues/#comments Wed, 26 May 2004 23:24:57 +0000 http://www.iosart.com/blog/archives/2004/05/26/3/ A release build of a MFC application crashes, while the Debug build works fine.

The crash analysis shows that the stack has been overwritten and thus destroyed.
Further analysis reveals that the crash occurs inside a ::SetWindowText call in a CEdit sub-classed object. This shouldn’t be my code, right? Wrong.

What was happening is that somewhere inside the call the framework called my OnUpdate handler (setup with ON_CONTROL_REFLECT_EX). The problem was that the handler was defined having a wrong prototype: BOOL OnUpdate(NMHDR* pNotifyStruct, LRESULT* result) instead of BOOL OnUpdate(). The framework doesn’t perform type checking – the function pointer is just being casted and the call is being made. So, no parameters are being pushed, but two parameters are popped – and the stuck is trashed.

]]>
https://blog.iosart.com/2004/05/26/mfc-blues/feed/ 0