The + character is valid in url query strings as a substitute for space or its hex-coded equivalent, %20.
When Angular bootstraps, $LocationProvider.$get initializes $location. $location.$$parse uses parseKeyValue (from inside matchAppURL) to decompose the query string into parameters. It calls the built-in decodeURIComponent which replaces hex escape sequences, but it does not replace "+" with space.
As a consequence, the plus character remains for $location.$$compile to encode as %2B which changes the unescaped, actual value of the parameter (as returned from $location.search().paramName) from "a b" to "a+b". This is incorrect.
The parseKeyValue function should be changed to scan the decoded value for '+' and replace it with space. This function is also used for manipulation of $location.search(), and in that scenario, '+' replacement is not correct, so the change would need to be parameterized so that '+' is replaced when parsing a parameter from the browser and left alone when parsing a parameter from the application.
Verified in angular 1.0.7 and 1.1.5.