On Sun, Sep 12, 2021 at 02:15:48AM +0200, Ævar Arnfjörð Bjarmason wrote: > This is what I'd been sitting on locally since that recent thread, I > polished it up a bit since Jeff King posted his version. > > The potential overflow bug I mentioned is in rebase.c. See > 5/7. "Potential" because it's not a bug now, but that code > intentionally considers a strvec, and then iterates it from nr-1 to 0, > and if it reaches 0 intentionally counts down one more to -1 to > indicate that it's visited all elements. > > We then check that with i >= 0, except of course if it becomes > unsigned that doesn't become -1, but rather it wraps around. You can also just use ssize_t, or you can compare against SIZE_MAX to catch the wraparound (there's some prior art in sort_revindex()). That said, I don't mind rewriting loops to count up rather than down. It usually makes them easier to follow (and in your patch 5, I do not see any reason we would need to count down rather than up; we do not even care where we find "-q", only that we found it. > The rest of this is all changes to have that s/int/size_t/ radiate > outwards, i.e. when we assign that value to a variable somewhere its > now a "size_t" instead of an "int" etc. I'm a little "meh" on some of these, for a few reasons: - anything calling into setup_revisions() eventually is just kicking the can anyway. And these are generally not buggy in the first place, since they're bounded argv creations. - passing a strvec instead of the broken-down pair is a less flexible interface. It's one thing if the callee benefits from seeing the strvec (say, because they may push more items onto it). But I think with strbufs, we have a general guideline that if a function _can_ take the bare pointer, then it should. (Sorry, I don't have a succinct reference to CodingGuidelines or anything like that; I feel like this is wisdom we came up with on the list in the early days of strbufs). - if we are going to pass a strvec, it should almost certainly be const, to make it clear how we intend to use it. So if we we wanted to try to reduce the int/size_t conversions here (and I don't mind doing it, but am not altogether sure it is a good use of time, because the rabbit hole runs deep), I think we ought to be switching to size_t everywhere-ish along whole call chains. Or possibly providing a checked size_to_int() which will safely catch and abort. These cases are largely stupid things that real people would never come across. The real goal is making sure we don't get hit with a memory safety bug (under-allocation, converting a big size_t to a negative int, etc). -Peff