Saturday 26 May 2012

The EU Cookie directive is impossible to implement

Well, OK, maybe not impossible, but it might as well be.

Here’s why.  If you include any content that’s not directly generated on your site, an http request to set a cookie from the third party site appears to be honoured by your browser.

For instance, I set up a file on my server that runs the following php on request for a particular javascript file:

<?php
header("Content-type: text/javascript");
header("Set-Cookie: GOTCHA=value; path=/; expires=Mon, 28-May-2012 00:00:00 GMT");

echo <<<EOT
alert('hello')
EOT

?>



If I then go to a third party site, like jsfiddle.net and include the javascript file from my server and run it, it turns out that a cookie is indeed set for the third party domain (my site containing the javascript).


Now, in theory the law requires the third party site to request permission before dropping the cookie, however, many third party affiliate networks are requiring the affiliate to request the permission.


Note that the Information Commissioner itself is vulnerable to this, because despite asking for permission, they include a script from another website.  In this case it’s: http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js


So as a result, they could unknowingly cause cookies to be deposited on your computer.

Sunday 20 May 2012

More bugs in the Toolkit ListPicker

We recently updated our Chromatic Tuner app, Tune Up, and after the update using the latest fixes for the Silverlight Toolkit was disappointed to find some new stack traces on the control panel.

As usual it’s a navigation bug, this time caused by a storyboard completing after something else has happened, in this case, someone pressed the start button after the navigation began.

As a result, the code in PickerPage.xaml.cs calls NavigationService.GoBack(); in the OnNavigatedTo handler.

Then the storyboard completes, and NavigationService.GoBack(); is called again while navigating.  We all know this is going straight to the exception handler.

The fix and issue are at http://silverlight.codeplex.com/workitem/10769 but I’ll duplicate it here.

private void OnClosedStoryboardCompleted(object sender, EventArgs e)
{
// Close the picker page
if (NavigationService.CanGoBack)
{
// Only do this if we can go back, or we crash
// navigate to start menu before this happens provokes.
NavigationService.GoBack();
}
}



But wait, there’s more!


While trying to diagnose this problem, I was playing around with the ListPicker trying to figure out exactly what might be going on, and I found another problem.


Immediately after you make your selection, the transition begins, and effectively you’ve made your selection.


But it’s actually possible to click on another item, and select that during the transition!  I consider this undesirable behaviour too.  You made your choice, and the transition began, yet you can change it at the last minute?  BZZZZ.  Wrong.


Here’s the fix for that one, again in ListPickerPage.xaml.cs:


private void ClosePickerPage()
{
IsOpen = false;
// AAW: disable picker on exit.
Picker.IsEnabled = false;
}

Saturday 19 May 2012

Don’t use NavigationOutTransition from the Toolkit

I’ve recently updated a bunch of our software at www.wieser-software.com/m and have been noticing while demonstrating it occasionally without a data connection, that it’s possible to end up with either a blank screen or two pages shown on top of each other as a result of navigation.

I think I’ve tracked it down to a bug in the Toolkit, though I can’t work out how to fix it.

The problem arises when you are transitioning away from a page with a NavigateOutTransition, and then end up navigating back into another page (maybe the same one) before that transition has been completed.

When this happens, your program will be unhappy.

The only way I’ve found for now to fix it is remove the NavigationOutTransition elements completely from my pages.

You can follow the issue here on the Silverlight Toolkit pages:

http://silverlight.codeplex.com/workitem/8293

Sunday 13 May 2012

Formatting a Data Bound TimeSpan on WP7

Today, I was attempting to format a data bound TimeSpan for our upcoming application using the Custom TimeSpan Format Strings provided on MSDN

Much to my surprise, no matter what I tried, it didn’t appear to format the text, and I’m not the only one to find this.

TimeSpan ts = TimeSpan.FromSeconds(1.24);
string st = string.Format(@"{0:hh\:mm\:ss}", dt);
// st = "00:00:01.2400000"


Clearly the seconds formatting is not working correctly.  And worse, the documentation states that the time separators are not placeholders.


In my case, I know my TimeSpan is always less than 24 hours, so I thought the best solution was to convert it to a DateTime using a converter.


public class TimespanToDateTimeConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return new DateTime(((TimeSpan) value).Ticks);
}

public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}


Now in my xaml, I do this to bind to an object named Elapsed:

 


<Grid>
<Grid.Resources>
<fwk:TimespanToDateTimeConverter x:Key="asDate" />
</Grid.Resources> ...
<TextBlock Text="{Binding Elapsed,
Converter={StaticResource asDate},
StringFormat='{0:HH\:mm\:ss\}'}"
/>

</Grid>

This neatly solves the problem, and in the process, delivers locale specific separators as well.

Friday 4 May 2012

One of our ListItems is missing! ListPicker Bug Alert!

I used the November ‘11 Silverlight Toolkit ListPicker control in one of my upcoming WP7 apps, and was surprised when impatiently, I started scrolling down while my full screen picker page was opening.

Unfortunately, when I got to the bottom of the page, some of the items were not visible, though vertical space was reserved for them.

Off to the source I went, and discovered that the ListPicker control initially sets every item on the page to be have a PlaneProjection with a RotationX of –90.  That would at least explain why my items weren’t visible.  They were rotated away from the field of view so they couldn’t be seen (Just like Calvin and Hobbes in 2D form)

So how did it happen?

Deep inside the ListPickerPage.xaml.cs file, in the UpdateVisualState function, there’s an IList<WeakReference> itemsInView that holds the list of items currently in view, then a few lines later, a Dispatcher.BeginInvoke on UpdateOutOfViewItems.

UpdateOutOfViewItems then collects the list of visible items again.  Only they might not be the same items.  In fact, any items that are new to the set will not be drawn correctly.

The Solution

The solution of course is to change the call to pass in the list of in-view items to the UpdateOutOfViewItems, changing the call to

Dispatcher.BeginInvoke(new Action(() => UpdateOutOfViewItems(itemsInView)));

and the signature to:

private void UpdateOutOfViewItems(IList<WeakReference> itemsInView)

and finally we don’t call GetItemsInViewPort in the UpdateOutOfViewItems.

I’ve added this fix as a hotfix to the SilverlightToolkit project here:

ListPickerPage.xaml.cs

Tuesday 1 May 2012

CryptAcquireContext fails again

Today I spent about two hours with a customer who was having problems installing some of our full version software.

When he ran the installation program, he was presented with a series of error messages, the first one being:

Error during CryptAcquireContext along with error code 0000054F or 1359

That error code translates to ERROR_INTERNAL_ERROR.

After some psychic debugging, I realized it probably had something to do with his user account and the way his machine had been configured by the manufacturer.

The default account settings some manufacturers use

I’m not exactly sure what was going on, but as I asked him what antivirus software he runs and the answer was none, it suddenly occurred to me that he probably only had only one user account on the machine, and that user account had no password.  Both of those guesses proved correct.

And sure enough, the problem was solved by doing the following:

  • Create a new administrator account on the machine
  • Create a password for the new administrator account
  • Log into that new account
  • Install the software