Opened 13 years ago
Closed 13 years ago
#3486 closed Bugs (fixed)
local_time::posix_time_zone_base::calc_zone Misuses String Iterator
Reported by: | Owned by: | az_sw_dude | |
---|---|---|---|
Milestone: | Boost 1.41.0 | Component: | date_time |
Version: | Boost 1.34.0 | Severity: | Showstopper |
Keywords: | calc_zone iterator | Cc: |
Description
calc_zone() starts like this:
void calc_zone(const string_type& obj){
const char_type empty_string[2] = {'\0'}; stringstream_type ss(empty_string); typename string_type::const_iterator sit = obj.begin(); string_type l_std_zone_abbrev, l_dst_zone_abbrev;
get 'std' name/abbrev while(std::isalpha(*sit)){
ss << *sit++;
}
Notice that sit is never compared against obj.end(). This code apparently assumes that some non-alpha character will appear, if only a null terminator. However, a checked STL flags *sit, in the conditional, as an error when trying to dereference the end iterator.
The particular example I encountered in which it failed was when obj was a std::string, of length 9, containing "Australia". There is no non-alpha character before advancing the iterator to the end, so operator *() fails with: "string iterator not dereferencable" in MSVC 8 (DevStudio 2005).
I suggest changing the loop to the following:
typename string_type::const_iterator it(obj.begin()); typename string_type::const_iterator end(obj.end()); get 'std' name/abbrev while (it != send && std::isalpha(*it)) {
ss << *it++;
}
(You can reuse end in the rest of the function, while you're at it!)
Change History (2)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I was just creating a local diff for 1.39 and realized that the iterator sit has been changed to a pointer, thus bypassing the checked iterator problem of the earlier version.
Sorry for the noise!
Wow! Trac really munged the code I entered and I forgot to s/send/end/ in the suggested change.
Later releases (I happened to have looked at the code from 1.33 when I copied the above) already do the equivalent of eit (obj_end). However, the bug remains, so here's the change needed for the trunk: