On Mon, Oct 26, 2026 at 2:19 PM Tomasz Kaminski <[email protected]> wrote:
> > > On Mon, Oct 26, 2026 at 2:12 PM Tomasz Kaminski <[email protected]> > wrote: > >> On Fri, Oct 23, 2026 at 2:58 PM Jonathan Wakely <[email protected]> >> wrote: >> >>> On Tue, 13 Oct 2026 at 21:09, Jonathan Wakely wrote: >>> > >>> > A very negative time point will stay negative when info.begin is >>> > subtracted from it, which means that a negative value will be passed to >>> > vector::reserve. That will convert to a huge size_t value, and the >>> > vector will throw length_error. This commit clamps the time point >>> > argument to be no less than the start of the zone's first info, so that >>> > `tp - info.begin` will be non-negative. >>> >> There are no zones and rules that apply before 1900, so I would suggest to >> change the reserve condition to something like: >> constexpr eariest_rule = 1900y/Jan/1; >> if (tp > eariest_rule) [[likely]] >> if (int n = ceil<years>(tp - >> std::max(info.begin, eariest_rule)).count()) >> new_infos.reserve(std::min(100, n * 2)); >> And let any user-made time zone database simply use normal vector growth >> algorithm. >> There is no point in allocating 2000 elements if someone asks for time at >> year 26 AC. >> > That is min not max, so we never allocate more than 100. Got confused. > >> >> This need to be backported up to 14, as the 2026e tzdata introduced a new >> entries that >> > That also implies that a backport isn't critical, as we will simply allocate 100 elements, for below zons, when asked about 1700, 783, e.t.c. > applies a rule on the first line (so such earily time is not already >> expanded): >> Z CST6CDT -6 US C%sT >> Z EST5EDT -5 US E%sT >> Z MST7MDT -7 US M%sT >> Z PST8PDT -8 US P%sT >> The earliest rule in US set in 1918., >> >> > >>> > This commit also changes it to chrono::abs(tp - info.begin). This is >>> > not strictly necessary now that tp is not less than info.begin, but it >>> > makes the code more robust. Even if a later change makes it possible >>> for >>> > the value to be negative again, we will not pass a negative value to >>> > vector::reserve. >>> > >>> > libstdc++-v3/ChangeLog: >>> > >>> > PR libstdc++/127815 >>> > * src/c++20/tzdb.cc (time_zone::_M_get_sys_info): Clamp >>> > parameter to start of first info. Use chrono::abs for argument >>> > to vector::reserve. >>> > * testsuite/std/time/time_zone/127815.cc: New test. >>> >>> gcc.sashiko.dev made some useful comments on this patch >>> >>> https://gcc.sashiko.dev/#/patchset/20261013200857.3698160-1-jwakely%40redhat.com >> >> >> The comments are valid; however, I do not think the fix for them should >> be combined into this patch. >> While expanding the initial sys_info to start at seconds::min() is >> unproblematic I think (we need to be >> carefull when converting to date), the standard is not clear, what should >> happen if zone specifiy >> UNTIL time for the last rule, and does not have line without any UNTIL. >> >
