From 472ce85bec1ae24e5d82ccd369ab4cd444bebb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Thu, 12 Feb 2015 15:32:27 -0800 Subject: [PATCH] Treat number components that overflow as strings If a number component is too large to be represented by uint32, simply start treating the component as a string instead of raising RuntimeError. --- ext/version_sorter/version_sorter.c | 22 ++++++++++++++-------- test/version_sorter_test.rb | 13 +++++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ext/version_sorter/version_sorter.c b/ext/version_sorter/version_sorter.c index 67424e0..103b3fe 100644 --- a/ext/version_sorter/version_sorter.c +++ b/ext/version_sorter/version_sorter.c @@ -112,20 +112,26 @@ parse_version_number(const char *string) if (isdigit(string[offset])) { uint32_t number = 0; + uint16_t start = offset; + int overflown = 0; while (isdigit(string[offset])) { - uint32_t old_number = number; - number = (10 * number) + (string[offset] - '0'); - - if (number < old_number) - rb_raise(rb_eRuntimeError, - "overflow when comparing numbers in version string"); + if (!overflown) { + uint32_t old_number = number; + number = (10 * number) + (string[offset] - '0'); + if (number < old_number) overflown = 1; + } offset++; } - version->comp[comp_n].number = number; - num_flags |= (1 << comp_n); + if (overflown) { + version->comp[comp_n].string.offset = start; + version->comp[comp_n].string.len = offset - start; + } else { + version->comp[comp_n].number = number; + num_flags |= (1 << comp_n); + } comp_n++; continue; } diff --git a/test/version_sorter_test.rb b/test/version_sorter_test.rb index bcee523..f97e6ef 100644 --- a/test/version_sorter_test.rb +++ b/test/version_sorter_test.rb @@ -30,4 +30,17 @@ def test_reverse_sorts_versions_correctly assert_equal sorted_versions, VersionSorter.rsort(versions) end + + def test_does_not_raise_on_number_overflow + big_numbers = [ + (2**32).to_s, + (2**32 + 1).to_s, + (2**32 + 2).to_s, + (2**32 - 2).to_s, + (2**32 - 1).to_s, + ] + randomized = big_numbers.sample(big_numbers.size) + + assert_equal big_numbers, VersionSorter.sort(randomized) + end end