CocoaPods / Core

The models used within the CocoaPods gem
MIT License
160 stars 349 forks source link

Version Comparison Issue with Mixed Numeric and String Prerelease Segments #752

Closed sagiwei closed 3 months ago

sagiwei commented 1 year ago

Per the Semantic Versioning Specification, prerelease versions 1.0.0-beta.3rd.1 and 1.0.0-beta.ios17.1 are different, the first expected to be less than the second one according to spec 11.4.3. However, CocoaPods currently treats these two versions as equal, leading to the installation of 1.0.0-beta.ios17.1 over 1.0.0-beta.3rd.1 when pod foo, ‘1.0.0-beta.3rd.1’ is used in the Podfile.

The issue lies in the compare_segments method of Pod::Version. The method fails to handle a case where the prerelease segments contain both String and Numeric elements, leading to an incorrect equality comparison when the types of elements at the same index differ.

Here's an example illustrating this issue:

Version.new('1.0.0-beta.3rd.1').prerelease_segments
# [beta, 3, rd, 1]

Version.new('1.0.0-beta.ios17.1').prerelease_segments
# [beta, ios, 17, 1]

# compare steps
'beta' == 'beta' # loop:0, true, next
3 <=> 'ios' # loop:1, nil, next
'rd' <=> '17' # loop:2, nil, next
1 == 1 # loop:3, true, next, exit

I've addressed this by adding a check in the lhs <=> rhs comparison to handle cases where it returns nil, determining the types of the two elements and returning the correct result per spec 11.4.3:

lib/cocoapods-core/version.rb

image

Fix on #754

sagiwei commented 7 months ago

@amorde could you check this issue and PR pls?