unascribed / FlexVer

A SemVer-compatible intuitive comparator for free-form versioning strings as seen in the wild, designed to sort versions like people do.
Creative Commons Zero v1.0 Universal
64 stars 10 forks source link

removeLeadingZeroes - deviation (?) from the spec #17

Closed John-Paul-R closed 1 year ago

John-Paul-R commented 1 year ago

I mostly want to verify that a certain quirk (in both the spec's example and the java & c# implementations (at least)) is intentional.

From the spec's advice on codepoint-wise comparison for "Numeric" parts:

Remove zeroes from the beginnings of both components until doing so would leave them as length zero. If their lengths differ, that difference is the result. Otherwise, iterate through each codepoint, and compare their digit values. If those differ, that difference is the result. If all the codepoints' digit values match, the result is equal. In psuedocode:

The example (modified slightly for clarity here. source):

componentA = removeLeadingZeroes(componentA)
componentB = removeLeadingZeroes(componentB)
if (componentA.length != componentB.length) return componentA.length <=> componentB.length
for i from 0 to componentA.length exclusive:
    let a = digit(componentA[i])
    let b = digit(componentB[i])
    if (a != b) return a <=> b
return 0

String removeLeadingZeroes(String component):
  if (component.length == 1) return component
  let i = 0
  while (i < a.length && digit(a[i]) == 0):
      i++
  return component.slice(i, component.length)

Notably, line one of removeLeadingZeroes early-outs for a length of 1, so '0' returns '0'. '00', however, would return ''. This would lead the subsequent length comparison to treat them as not-equal. '000' and '00' however, would be treated as equal.

The description, and the earlier section, suggesting "integer parsing" as a valid way to compare numeric parts suggests to me that this may be a bug in the example/implementation.

If that's the case, I can put up a PR to resolve the bug where I notice it (treating '0' and '00' as equal). Just lmk!

unascribed commented 1 year ago

Hm. The intent is that 00 should return 0, but I am an idiot and forgot that i will be one greater than it was in the final repetition of the loop.