public inbox for gcc-prs@sourceware.org help / color / mirror / Atom feed
From: peturr02@ru.is To: gcc-gnats@gcc.gnu.org Subject: libstdc++/9875: filebuf doesn't handle codecvt::encoding() > 1 Date: Thu, 27 Feb 2003 10:36:00 -0000 [thread overview] Message-ID: <20030227102718.13478.qmail@sources.redhat.com> (raw) >Number: 9875 >Category: libstdc++ >Synopsis: filebuf doesn't handle codecvt::encoding() > 1 >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: sw-bug >Submitter-Id: net >Arrival-Date: Thu Feb 27 10:36:01 UTC 2003 >Closed-Date: >Last-Modified: >Originator: peturr02@ru.is >Release: gcc-3.2.1 >Organization: >Environment: Red Hat Linux 8.0 >Description: Many basic_filebuf members (at least seekoff, seekpos, sync, overflow, underflow) can't handle fixed width multibyte encodings (where codecvt<>::encoding() > 1). It seems that every place _M_file.seekoff is called, it is assumed that codecvt<>::encoding() == 1. >How-To-Repeat: See attachment. Note that this test is incomplete because the bug in seekoff shadows some of the other bugs. >Fix: >Release-Note: >Audit-Trail: >Unformatted: ----gnatsweb-attachment---- Content-Type: text/plain; name="seekoffbug.cc" Content-Disposition: inline; filename="seekoffbug.cc" #include <fstream> #include <locale> #include <algorithm> #include <cstring> #undef NDEBUG #include <cassert> class Cvt : public std::codecvt<wchar_t, char, mbstate_t> { protected: virtual std::codecvt_base::result do_out(std::mbstate_t&, const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next, char* to, char* to_end, char*& to_next) const { std::size_t from_len = from_end - from; std::size_t to_len = (to_end - to) / sizeof(wchar_t); std::size_t len = std::min(from_len, to_len); std::memcpy(to, from, len * sizeof(wchar_t)); from_next = from + len; to_next = to + len * sizeof(wchar_t); return from_next == from_end ? std::codecvt_base::ok : std::codecvt_base::partial; } virtual std::codecvt_base::result do_in(std::mbstate_t&, const char* from, const char* from_end, const char*& from_next, wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const { std::size_t from_len = (from_end - from) / sizeof(wchar_t); std::size_t to_len = to_end - to; std::size_t len = std::min(from_len, to_len); std::memcpy(to, from, len * sizeof(wchar_t)); from_next = from + len * sizeof(wchar_t); to_next = to + len; return from_next == from_end ? std::codecvt_base::ok : std::codecvt_base::partial; } virtual std::codecvt_base::result do_unshift(std::mbstate_t&, char*, char*, char*&) const { return std::codecvt_base::noconv; } virtual int do_encoding() const throw() { return sizeof(wchar_t); } virtual bool do_always_noconv() const throw() { return false; } virtual int do_length(std::mbstate_t&, const char* from, const char* end, std::size_t max) { std::size_t len = (end - from) / sizeof(wchar_t); return std::min(len, max) * sizeof(wchar_t); } virtual int do_max_length() const throw() { return sizeof(wchar_t); } }; void test1() { using namespace std; // seekoff wfilebuf fb; fb.pubimbue(locale(locale::classic(), new Cvt)); fb.open("tmp", ios_base::out | ios_base::in | ios_base::trunc); fb.sputn(L"0123456789", 10); fb.pubseekoff(-3, ios_base::cur); assert(fb.sgetc() == L'7'); fb.pubseekoff(-3, ios_base::cur); assert(fb.sgetc() == L'4'); fb.close(); } void test2() { using namespace std; // seekpos wfilebuf fb; fb.pubimbue(locale(locale::classic(), new Cvt)); fb.open("tmp", ios_base::out | ios_base::in | ios_base::trunc); fb.sputn(L"0123456789", 10); streampos p1 = fb.pubseekoff(0, ios_base::cur); assert(p1 != streampos(-1)); fb.sputc(L'a'); streampos p2 = fb.pubseekpos(p1); assert(p2 != streampos(-1)); assert(p2 == p1); assert(fb.sgetc() == L'a'); fb.pubseekoff(0, ios_base::beg); wchar_t buf[11]; streamsize s1 = fb.sgetn(buf, 11); assert(s1 == 11); assert(!wmemcmp(buf, L"0123456789a", 11)); fb.close(); } void test3() { using namespace std; // overflow locale loc (locale::classic(), new Cvt); wfilebuf fb1; fb1.pubimbue(loc); fb1.open("tmp", ios_base::out | ios_base::trunc); fb1.sputn(L"0123456789", 10); fb1.close(); wfilebuf fb2; fb2.pubimbue(loc); fb2.open("tmp", ios_base::in | ios_base::out); fb2.sputc(L'a'); fb2.close(); wfilebuf fb3; fb3.pubimbue(loc); fb3.open("tmp", ios_base::in); assert(fb3.is_open()); wchar_t buf[10]; streamsize s1 = fb3.sgetn(buf, 10); assert(s1 == 10); assert(!wmemcmp(buf, L"a123456789", 10)); fb3.close(); } int main() { test1(); test2(); test3(); return 0; }
next reply other threads:[~2003-02-27 10:36 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top 2003-02-27 10:36 peturr02 [this message] 2003-02-28 22:55 paolo 2003-03-01 10:44 paolo 2003-03-03 10:56 Pétur Runólfsson 2003-03-03 11:06 Paolo Carlini 2003-03-03 18:46 Pétur Runólfsson
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=20030227102718.13478.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).