public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: peturr02@ru.is To: gcc-gnats@gcc.gnu.org Subject: libstdc++/9224: Incorrect type of first parameter and incorrect return value of codecvt<>::length (DR75,DR305) Date: Wed, 08 Jan 2003 11:06:00 -0000 [thread overview] Message-ID: <20030108110330.28491.qmail@sources.redhat.com> (raw) >Number: 9224 >Category: libstdc++ >Synopsis: Incorrect type of first parameter and incorrect return value of codecvt<>::length (DR75,DR305) >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Wed Jan 08 03:06:00 PST 2003 >Closed-Date: >Last-Modified: >Originator: peturr02@ru.is >Release: gcc-3.2.1 >Organization: >Environment: Red Hat Linux 8.0 >Description: 1. According to the resolution of Library Defect Report 75 < http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#75 > the type of the first parameter of codecvt<>::length and do_length should be StateT&, not const StateT&. 2. DR75 also sets a requirement that the effect of length upon state be "as if" do_in were called. This does not seem to hold for codecvt<wchar_t, char, mbstate_t> or codecvt<I, E, __enc_traits>. 3. The rationale for DR302 makes it clear that when do_length is called with an invalid input sequence, it should return the number of elements that could be successfully converted. The current implementation of do_length makes no attempt to check if the input is valid. 4. DR305 leaves codecvt<wchar_t, char, mbstate_t> mostly implementation defined, but that definition appears to be missing (except for some vague talk about wcsrtombs). I can't find anything on what do_in does to state or what it considers invalid input, so it is not possible to test 2 or 3. >How-To-Repeat: This should test for item 1: class MyCvt : public codecvt<char, char, mbstate_t> { public: bool called; MyCvt() : called(false) { } int do_length(mbstate_t&, const char*, const char*, size_t) { called = true; return 0; } }; const char* p = NULL; mbstate_t s; MyCvt mc; mc.length(s, p, p, 0); assert(mc.called); >Fix: See attachment. The additional requirement that the effect on state be "as if" do_in were called is achieved by calling do_in. This is not neccessary for codecvt<char, char, mbstate_t> as DR19 clearly states that do_in shall not modify state if it returns noconv. The return value of codecvt<wchar_t, char, mbstate_t>::do_length is also modified to reflect DR305 and the rationale for DR302. This depends on do_in always setting from_next correctly, regardless of return value (see DR382). This seems not to be the case, but that is also a problem when calling do_in directly and is a separate issue. Patch is against gcc-20021230, but also applies to gcc-3.2.1. Tested on Red Hat Linux 8.0 on x86. >Release-Note: >Audit-Trail: >Unformatted: ----gnatsweb-attachment---- Content-Type: text/plain; name="dr75.patch" Content-Disposition: inline; filename="dr75.patch" diff -c3pr /home/petur/src/gcc-20021230/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h gcc-20021230/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h *** /home/petur/src/gcc-20021230/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h 2002-05-26 14:35:04.000000000 +0000 --- gcc-20021230/libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h 2003-01-07 20:11:28.000000000 +0000 *************** *** 230,236 **** do_always_noconv() const throw(); virtual int ! do_length(const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int --- 230,236 ---- do_always_noconv() const throw(); virtual int ! do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int *************** *** 447,455 **** template<typename _InternT, typename _ExternT> int codecvt<_InternT, _ExternT, __enc_traits>:: ! do_length(const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const ! { return min(__max, static_cast<size_t>(__end - __from)); } #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS // 74. Garbled text for codecvt::do_max_length --- 447,463 ---- template<typename _InternT, typename _ExternT> int codecvt<_InternT, _ExternT, __enc_traits>:: ! do_length(state_type& __state, const extern_type* __from, const extern_type* __end, size_t __max) const ! { ! size_t __blen = __max * sizeof(intern_type); ! intern_type* __buf = ! reinterpret_cast<intern_type*>(__builtin_alloca(__blen)); ! const extern_type* __from_next; ! this->in(__state, __from, __end, __from_next, ! __buf, __buf + __max, __buf); ! return __from_next - __from; ! } #ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS // 74. Garbled text for codecvt::do_max_length diff -c3pr /home/petur/src/gcc-20021230/libstdc++-v3/include/bits/codecvt.h gcc-20021230/libstdc++-v3/include/bits/codecvt.h *** /home/petur/src/gcc-20021230/libstdc++-v3/include/bits/codecvt.h 2002-09-11 03:36:45.000000000 +0000 --- gcc-20021230/libstdc++-v3/include/bits/codecvt.h 2003-01-07 19:38:14.000000000 +0000 *************** *** 106,112 **** { return this->do_always_noconv(); } int ! length(const state_type& __state, const extern_type* __from, const extern_type* __end, size_t __max) const { return this->do_length(__state, __from, __end, __max); } --- 106,112 ---- { return this->do_always_noconv(); } int ! length(state_type& __state, const extern_type* __from, const extern_type* __end, size_t __max) const { return this->do_length(__state, __from, __end, __max); } *************** *** 144,150 **** do_always_noconv() const throw() = 0; virtual int ! do_length(const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const = 0; virtual int --- 144,150 ---- do_always_noconv() const throw() = 0; virtual int ! do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const = 0; virtual int *************** *** 204,210 **** do_always_noconv() const throw(); virtual int ! do_length(const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int --- 204,210 ---- do_always_noconv() const throw(); virtual int ! do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int *************** *** 264,270 **** do_always_noconv() const throw(); virtual int ! do_length(const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int --- 264,270 ---- do_always_noconv() const throw(); virtual int ! do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int *************** *** 324,330 **** bool do_always_noconv() const throw(); virtual ! int do_length(const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int --- 324,330 ---- bool do_always_noconv() const throw(); virtual ! int do_length(state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const; virtual int diff -c3pr /home/petur/src/gcc-20021230/libstdc++-v3/src/codecvt.cc gcc-20021230/libstdc++-v3/src/codecvt.cc *** /home/petur/src/gcc-20021230/libstdc++-v3/src/codecvt.cc 2002-10-08 23:32:23.000000000 +0000 --- gcc-20021230/libstdc++-v3/src/codecvt.cc 2003-01-07 20:11:30.000000000 +0000 *************** namespace std *** 106,112 **** int codecvt<char, char, mbstate_t>:: ! do_length (const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { return min(__max, static_cast<size_t>(__end - __from)); } --- 106,112 ---- int codecvt<char, char, mbstate_t>:: ! do_length (state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const { return min(__max, static_cast<size_t>(__end - __from)); } *************** namespace std *** 152,160 **** int codecvt<wchar_t, char, mbstate_t>:: ! do_length(const state_type&, const extern_type* __from, const extern_type* __end, size_t __max) const ! { return min(__max, static_cast<size_t>(__end - __from)); } int codecvt<wchar_t, char, mbstate_t>:: --- 152,168 ---- int codecvt<wchar_t, char, mbstate_t>:: ! do_length(state_type& __state, const extern_type* __from, const extern_type* __end, size_t __max) const ! { ! size_t __blen = __max * sizeof(intern_type); ! intern_type* __buf = ! reinterpret_cast<intern_type*>(__builtin_alloca(__blen)); ! const extern_type* __from_next; ! this->in(__state, __from, __end, __from_next, ! __buf, __buf + __max, __buf); ! return __from_next - __from; ! } int codecvt<wchar_t, char, mbstate_t>::
reply other threads:[~2003-01-08 11:06 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20030108110330.28491.qmail@sources.redhat.com \ --to=peturr02@ru.is \ --cc=gcc-gnats@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).