Note that Microsoft uses
[Pure] exclusively in the context of Code Contracts (as opposed to, say, optimizing code during compilation or runtime). In this context, if the method doesn't make visible state changes, the method is pure. As simple as that.
When Code Contracts were introduced, the
[Pure] attribute was added sporadically and sometimes inconsistently, and a series of methods which are pure didn't have this attribute. Back then I was working on several critical projects which required us to use Code Contracts, and I had to do a lot of wrappers around .NET Framework's assemblies just to add proper contracts, for instance saying that
Random.NextDouble will always return a value which is greater than or equal to 0.0 and less than 1.0. The same goes for
Chances are, some developers at Microsoft needed to work with
string.Trim within the code covered by Code Contracts, and so it got its attribute, but nobody used
string.Substring. Or there may be other considerations why the later didn't receive its well deserved attribute.
Anyway, if you rely on Code Contracts, create a wrapper and add the missing attribute.
If you don't rely on Code Contracts, ignore those attributes.