Rare bug in SharePoint with IE9 when account names have commas

Configured a certain way, Active Directory will generate account names like so: “Lastname, Firstname”. Although SharePoint strongly recommends you not to use account names with special characters, it seems to mostly be able to handle this.

Now, user links generated with SharePoint’s renderUserField look something like this:

Which works perfectly fine. However, with commas in the account name, the account name part of the link will instead look like this: “turing%2C%20alan”. URL encoded comma is %2C and space is %20. So far, so good. Try it in Firefox, Chrome, IE10+, no problems. Try it in IE8, works great. But not IE9. Clicking the link in IE9 sends you to a url containing “turing%252C%20alan”. Spot the error? %252C looks a lot like double encoding. And it is. But why is this only a problem in IE9? I worked my way through many suspects, including encodeURI and escapeProperly/unescapeProperly (yes, these do exist in SharePoint). Nothing came up. And the odd thing is that the URL in the link I click doesn’t match the URL I end up at. This because of the onClick handler, of course!

After a lot more work, I find out why this bug is only active in IE9. There’s a piece of code, triggered by the click handler, that decodes the URL encoded link, does some stuff with it, and encodes it again. This code is blocked by two conditions. It is only reached if the MDS is on and the browser is Internet Explorer 9 or less. MDS doesn’t work in IE8. That only leaves IE9.

But why the double encoding? The thing is, encodeURI will not touch commas, they don’t need encoding. Try it out in your console:

And of course, if you encode something and then decode it the same way, you should get the original string back, right? What if you use encodeURIComponent to encode, and encodeURI to decode? Bad things happen. Because encodeURIComponent _does_ encode commas. So lets say you know a certain string is encoded already, and you want to decode it, do some stuff with it and encode it again. You might write this:

Try that code with this URL: “http://example.com/turing%2C%20alan/”. You should get “http://example.com/turing%252C%20alan/”. Mystery solved!

But that just raises another question, really. Why was the comma urlencoded in the first place? The culprit can be found in SharePoint’s “init.js”.

Back to the onClick handler. It calls a function called GoToLinkOrDialogNewWindow, which uses the href of the a tag you clicked and, amongst other things, creates a URI object from it. URI is a type of object defined in “init.js”, and has lots of nifty functionality. It automatically encodes its content too, and when you call getString on the object, you get a nicely formatted URL string. Except, of course, when there’s a comma in it. You see, URI doesn’t use encodeURI. Instead, it breaks the link up into parts, a bit like this: http-:-//-example.com-/turing, alan/ (using – as a delimiter). It then fastidiously encodes each component, of course, using encodeURIComponent.

So who’s wrong? No one, really. The problem is that one part of SharePoint assumes a URL to be encoded using encodeURI. Another part of SharePoint encodes the URL by looping over parts of it and calling encodeURIComponent. Communication breakdown.

SharePoint 2010 Security Breach: Export to Excel Ignores Security Trimming

I’m currently working on a project where there are lists where permissions are broken and set on the list item level. Basically there are different groups of users, and some should see all items, and some should only be able to view a fiew of them. Now, all of these users have contribute, and can use the ‘Export to Excel’ function, which is very important to them. Now here is the issue I found out just a few days ago. Export to Excel ignores security trimming!

So what does this actually mean? Let me illustrate using a fictional example:

I have a list called Accounts, where I store important information about clients and the business I have with them. Some accounts are secret, so I break the permission inheritance on them. Let’s say I have three accounts, A, B and C. Account A is secret, and I’m the only one who has permissions to view it. Now, I have a group of colleagues, who also have access to the Accounts list, and can contribute to it. But when they visit the list, they can’t see Account A, since I have removed their permissions from it. Now what happens when one of my colleagues use the Export to Excel function? You would think that the generated Excel file would only contain accounts B and C. But no! The export function ignores the permissions of the user and only checks if the user has permissions to acces the function itself. The result is the user being able to see account A as well, giving it access to information that should be hidden.

In my opinion, this has to be regarded as a bug, because if this is by design, it’s poor design indeed.

I tested this in SharePoint 2013, and the bug seems to be fixed. Will try and see if there is a hotfix or CU fixing this issue for SP 2010.

After installing the July 2014 CU for SharePoint Server 2010, I can confirm that the bug is not fixed. It has to have been fixed for SP 2013 only.

Programmatically move a SPListItem to another folder in the same list

I had a hard time finding a good source for this, and therefore decided to write a short post about it.

First of all, I want to say that I am against the use of folders unless you absolutely need them. They add unnecessary complexity, and you can have the benefits of folders without many of the drawbacks by using metadata instead, for example with managed metadata fields. However, as there are no OOTB (out of the box) way of handling permissions for a group of items based in their metadata, folders MIGHT be useful for that purpose. There are other solutions though.

Now to the task at hand, moving a SPListItem based on it’s metadata, and then moving it to a subfolder in the same list. In my example, I will be moving the item in an event receiver.

What we need to do is to check the SPFileSystemObjectType of the SPListItem. This value will actually be File, even it it’s not a document library. Regular list items will also return object type File. This is only needed if you don’t want to move folders the same way.

This code assumes you have already got your SPListItem:

Then we need to get the file object of the item. The file object will exist even if the list is not a library, and this code will work for documents and list items alike.

Then we want to build the new destination path were the item will be moved to. The path should follow the pattern: “<web url>/<list rootfolder url>/<subfolder>/<item Id>._000″

And lastly, we simply call the SPFile.MoveTo method on our file object, and add the destination path.

And that’s it. Put this in an ItemAdded function in an event receiver for a list and items will automatically be moved to the correct folder. Below is my complete example where I also make sure the folder exist before moving the item.