joshua353 / update-engine

Automatically exported from code.google.com/p/update-engine
Apache License 2.0
0 stars 0 forks source link

Versions are compared as raw strings #28

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create a server plist with predicate "Ticket.version < 'R9'"
2. ./EngineRunner dryrun -url $urlToServerPlist -version R10 -productid 
EngineRunner

What is the expected output? What do you see instead?

Should say "No products to update". Will instead say EngineRunner should 
update, because it believes R10 < R9.

The same is true with standard project numbering: 1.0.10 < 1.0.9 as far as 
UpdateEngine is concerned.

The default plist generated by the script uses !=, as do the samples on the 
wiki, but this isn't a good idea in real life. It takes time for updates to 
become visible through caches (e.g., up to 24 hours for Cloudfront to propagate 
a change worldwide, plus an hour for the old version to live inside an intranet 
cache). During that time, someone who's downloaded R10 or 1.0.10 may see the 
server plist for R9 or 1.0.9, and UpdateEngine will "update" them to the older 
version.

Given that Update Engine is itself at R9, this seems like a serious looming 
problem, unless you're planning to skip to R90 or start counting hexidecimally 
or something.

What version of the product are you using? On what operating system?

Pulled from svn 2011-04-11T13:52-08, which is probably R9, but I'm not positive 
of that.

Snow Leopard 10.6.6.

Please provide any additional information below.

I tried a number of workarounds. For example, NSPredicate handles arrays and 
numbers as well as strings, so you can write "Ticket.version &lt; { 1, 0, 9 
}"... but then you need some way to get  { 1, 0, 10 } out of the ticket instead 
of '1.0.10', or you'll just end up with an error from the predicate as it tries 
to call [NSArray length] on an NSString.

I haven't done too much NSPredicate programming, but if [KSTicket version] 
returned a KSVersionString instead of an NSString, and KSVersionString had 
comparison methods vs. NSString that did the right thing, would that be enough 
to magically work? Or is there a different way to extend NSPredicate to use 
custom comparators?

I think a simple workable comparison rule is something like this: Split the 
string around each substring of digits, converting the digit substrings into 
integers, and then compare the arrays. So, for example, "R1.10b" is { "R", 1, 
10, "b" }, which will be greater than { "R", 1, 9 }. Of course that "b" had 
better be an openssl-style revision, not short for "beta"; "R1.10beta2" is 
going to show up as greater than final "R1.10"... but you obviously can't 
handle both cases in one rule. Anyway, this rule would handle Update Engine 
itself, and the vast majority of projects out there.

Original issue reported on code.google.com by abarn...@gmail.com on 11 Apr 2011 at 11:03

GoogleCodeExporter commented 8 years ago
A simpler way to describe what I tried to get across in the last paragraph: 
NSNumericSearch.

(I still don't know the best way to get NSPredicate to do this; it may involve 
creating a KSVersionString and having its compare: call [super compare:other 
options:NSNumericSearch] instead of [super compare:other]?)

Original comment by abarn...@gmail.com on 12 Apr 2011 at 12:35