1*4882a593SmuzhiyunFrom 0d0dc9e42f27a743171700bcd2ba508ff6e760f9 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Florian Weimer <fweimer@redhat.com> 3*4882a593SmuzhiyunDate: Mon, 20 May 2019 21:54:57 +0200 4*4882a593SmuzhiyunSubject: [PATCH 08/20] libio: Remove codecvt vtable [BZ #24588] 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunThe codecvt vtable is not a real vtable because it also contains the 7*4882a593Smuzhiyunconversion state data. Furthermore, wide stream support was added to 8*4882a593SmuzhiyunGCC 3.0, after a C++ ABI bump, so there is no compatibility 9*4882a593Smuzhiyunrequirement with libstdc++. 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunThis change removes several unmangled function pointers which could 12*4882a593Smuzhiyunbe used with a corrupted FILE object to redirect execution. (libio 13*4882a593Smuzhiyunvtable verification did not cover the codecvt vtable.) 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunReviewed-by: Yann Droneaud <ydroneaud@opteya.com> 16*4882a593SmuzhiyunReviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> 17*4882a593Smuzhiyun(cherry picked from commit 09e1b0e3f6facc1af2dbcfef204f0aaa8718772b) 18*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 19*4882a593Smuzhiyun--- 20*4882a593Smuzhiyun libio/fileops.c | 3 - 21*4882a593Smuzhiyun libio/iofgetpos.c | 3 +- 22*4882a593Smuzhiyun libio/iofgetpos64.c | 3 +- 23*4882a593Smuzhiyun libio/iofsetpos.c | 3 +- 24*4882a593Smuzhiyun libio/iofsetpos64.c | 3 +- 25*4882a593Smuzhiyun libio/iofwide.c | 132 ++++++-------------------------------------- 26*4882a593Smuzhiyun libio/libio.h | 32 ----------- 27*4882a593Smuzhiyun libio/libioP.h | 29 +++++++++- 28*4882a593Smuzhiyun libio/wfileops.c | 89 +++++++++++++++-------------- 29*4882a593Smuzhiyun 9 files changed, 92 insertions(+), 205 deletions(-) 30*4882a593Smuzhiyun 31*4882a593Smuzhiyundiff --git a/libio/fileops.c b/libio/fileops.c 32*4882a593Smuzhiyunindex c9c5cbcc..dd66cc67 100644 33*4882a593Smuzhiyun--- a/libio/fileops.c 34*4882a593Smuzhiyun+++ b/libio/fileops.c 35*4882a593Smuzhiyun@@ -331,9 +331,6 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode, 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun cc = fp->_codecvt = &fp->_wide_data->_codecvt; 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun- /* The functions are always the same. */ 40*4882a593Smuzhiyun- *cc = __libio_codecvt; 41*4882a593Smuzhiyun- 42*4882a593Smuzhiyun cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; 43*4882a593Smuzhiyun cc->__cd_in.__cd.__steps = fcts.towc; 44*4882a593Smuzhiyun 45*4882a593Smuzhiyundiff --git a/libio/iofgetpos.c b/libio/iofgetpos.c 46*4882a593Smuzhiyunindex 8177326c..808ddc47 100644 47*4882a593Smuzhiyun--- a/libio/iofgetpos.c 48*4882a593Smuzhiyun+++ b/libio/iofgetpos.c 49*4882a593Smuzhiyun@@ -70,8 +70,7 @@ _IO_new_fgetpos (FILE *fp, __fpos_t *posp) 50*4882a593Smuzhiyun else 51*4882a593Smuzhiyun { 52*4882a593Smuzhiyun posp->__pos = pos; 53*4882a593Smuzhiyun- if (fp->_mode > 0 54*4882a593Smuzhiyun- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) 55*4882a593Smuzhiyun+ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) 56*4882a593Smuzhiyun /* This is a stateful encoding, safe the state. */ 57*4882a593Smuzhiyun posp->__state = fp->_wide_data->_IO_state; 58*4882a593Smuzhiyun } 59*4882a593Smuzhiyundiff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c 60*4882a593Smuzhiyunindex 0ec54131..5a0d8bd7 100644 61*4882a593Smuzhiyun--- a/libio/iofgetpos64.c 62*4882a593Smuzhiyun+++ b/libio/iofgetpos64.c 63*4882a593Smuzhiyun@@ -54,8 +54,7 @@ _IO_new_fgetpos64 (FILE *fp, __fpos64_t *posp) 64*4882a593Smuzhiyun else 65*4882a593Smuzhiyun { 66*4882a593Smuzhiyun posp->__pos = pos; 67*4882a593Smuzhiyun- if (fp->_mode > 0 68*4882a593Smuzhiyun- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) 69*4882a593Smuzhiyun+ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) 70*4882a593Smuzhiyun /* This is a stateful encoding, safe the state. */ 71*4882a593Smuzhiyun posp->__state = fp->_wide_data->_IO_state; 72*4882a593Smuzhiyun } 73*4882a593Smuzhiyundiff --git a/libio/iofsetpos.c b/libio/iofsetpos.c 74*4882a593Smuzhiyunindex da48b27c..0cbe3b79 100644 75*4882a593Smuzhiyun--- a/libio/iofsetpos.c 76*4882a593Smuzhiyun+++ b/libio/iofsetpos.c 77*4882a593Smuzhiyun@@ -58,8 +58,7 @@ _IO_new_fsetpos (FILE *fp, const __fpos_t *posp) 78*4882a593Smuzhiyun else 79*4882a593Smuzhiyun { 80*4882a593Smuzhiyun result = 0; 81*4882a593Smuzhiyun- if (fp->_mode > 0 82*4882a593Smuzhiyun- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) 83*4882a593Smuzhiyun+ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) 84*4882a593Smuzhiyun /* This is a stateful encoding, restore the state. */ 85*4882a593Smuzhiyun fp->_wide_data->_IO_state = posp->__state; 86*4882a593Smuzhiyun } 87*4882a593Smuzhiyundiff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c 88*4882a593Smuzhiyunindex 29da9814..695a8328 100644 89*4882a593Smuzhiyun--- a/libio/iofsetpos64.c 90*4882a593Smuzhiyun+++ b/libio/iofsetpos64.c 91*4882a593Smuzhiyun@@ -48,8 +48,7 @@ _IO_new_fsetpos64 (FILE *fp, const fpos64_t *posp) 92*4882a593Smuzhiyun else 93*4882a593Smuzhiyun { 94*4882a593Smuzhiyun result = 0; 95*4882a593Smuzhiyun- if (fp->_mode > 0 96*4882a593Smuzhiyun- && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0) 97*4882a593Smuzhiyun+ if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0) 98*4882a593Smuzhiyun /* This is a stateful encoding, safe the state. */ 99*4882a593Smuzhiyun fp->_wide_data->_IO_state = posp->__state; 100*4882a593Smuzhiyun } 101*4882a593Smuzhiyundiff --git a/libio/iofwide.c b/libio/iofwide.c 102*4882a593Smuzhiyunindex d8ec6642..0e9e7dd5 100644 103*4882a593Smuzhiyun--- a/libio/iofwide.c 104*4882a593Smuzhiyun+++ b/libio/iofwide.c 105*4882a593Smuzhiyun@@ -39,44 +39,6 @@ 106*4882a593Smuzhiyun #include <sysdep.h> 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun-/* Prototypes of libio's codecvt functions. */ 110*4882a593Smuzhiyun-static enum __codecvt_result do_out (struct _IO_codecvt *codecvt, 111*4882a593Smuzhiyun- __mbstate_t *statep, 112*4882a593Smuzhiyun- const wchar_t *from_start, 113*4882a593Smuzhiyun- const wchar_t *from_end, 114*4882a593Smuzhiyun- const wchar_t **from_stop, char *to_start, 115*4882a593Smuzhiyun- char *to_end, char **to_stop); 116*4882a593Smuzhiyun-static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt, 117*4882a593Smuzhiyun- __mbstate_t *statep, char *to_start, 118*4882a593Smuzhiyun- char *to_end, char **to_stop); 119*4882a593Smuzhiyun-static enum __codecvt_result do_in (struct _IO_codecvt *codecvt, 120*4882a593Smuzhiyun- __mbstate_t *statep, 121*4882a593Smuzhiyun- const char *from_start, 122*4882a593Smuzhiyun- const char *from_end, 123*4882a593Smuzhiyun- const char **from_stop, wchar_t *to_start, 124*4882a593Smuzhiyun- wchar_t *to_end, wchar_t **to_stop); 125*4882a593Smuzhiyun-static int do_encoding (struct _IO_codecvt *codecvt); 126*4882a593Smuzhiyun-static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, 127*4882a593Smuzhiyun- const char *from_start, 128*4882a593Smuzhiyun- const char *from_end, size_t max); 129*4882a593Smuzhiyun-static int do_max_length (struct _IO_codecvt *codecvt); 130*4882a593Smuzhiyun-static int do_always_noconv (struct _IO_codecvt *codecvt); 131*4882a593Smuzhiyun- 132*4882a593Smuzhiyun- 133*4882a593Smuzhiyun-/* The functions used in `codecvt' for libio are always the same. */ 134*4882a593Smuzhiyun-const struct _IO_codecvt __libio_codecvt = 135*4882a593Smuzhiyun-{ 136*4882a593Smuzhiyun- .__codecvt_destr = NULL, /* Destructor, never used. */ 137*4882a593Smuzhiyun- .__codecvt_do_out = do_out, 138*4882a593Smuzhiyun- .__codecvt_do_unshift = do_unshift, 139*4882a593Smuzhiyun- .__codecvt_do_in = do_in, 140*4882a593Smuzhiyun- .__codecvt_do_encoding = do_encoding, 141*4882a593Smuzhiyun- .__codecvt_do_always_noconv = do_always_noconv, 142*4882a593Smuzhiyun- .__codecvt_do_length = do_length, 143*4882a593Smuzhiyun- .__codecvt_do_max_length = do_max_length 144*4882a593Smuzhiyun-}; 145*4882a593Smuzhiyun- 146*4882a593Smuzhiyun- 147*4882a593Smuzhiyun /* Return orientation of stream. If mode is nonzero try to change 148*4882a593Smuzhiyun the orientation first. */ 149*4882a593Smuzhiyun #undef _IO_fwide 150*4882a593Smuzhiyun@@ -119,9 +81,6 @@ _IO_fwide (FILE *fp, int mode) 151*4882a593Smuzhiyun assert (fcts.towc_nsteps == 1); 152*4882a593Smuzhiyun assert (fcts.tomb_nsteps == 1); 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun- /* The functions are always the same. */ 155*4882a593Smuzhiyun- *cc = __libio_codecvt; 156*4882a593Smuzhiyun- 157*4882a593Smuzhiyun cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps; 158*4882a593Smuzhiyun cc->__cd_in.__cd.__steps = fcts.towc; 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun@@ -151,11 +110,11 @@ _IO_fwide (FILE *fp, int mode) 161*4882a593Smuzhiyun } 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun-static enum __codecvt_result 165*4882a593Smuzhiyun-do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, 166*4882a593Smuzhiyun- const wchar_t *from_start, const wchar_t *from_end, 167*4882a593Smuzhiyun- const wchar_t **from_stop, char *to_start, char *to_end, 168*4882a593Smuzhiyun- char **to_stop) 169*4882a593Smuzhiyun+enum __codecvt_result 170*4882a593Smuzhiyun+__libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, 171*4882a593Smuzhiyun+ const wchar_t *from_start, const wchar_t *from_end, 172*4882a593Smuzhiyun+ const wchar_t **from_stop, char *to_start, char *to_end, 173*4882a593Smuzhiyun+ char **to_stop) 174*4882a593Smuzhiyun { 175*4882a593Smuzhiyun enum __codecvt_result result; 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun@@ -203,57 +162,11 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, 178*4882a593Smuzhiyun } 179*4882a593Smuzhiyun 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun-static enum __codecvt_result 182*4882a593Smuzhiyun-do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, 183*4882a593Smuzhiyun- char *to_start, char *to_end, char **to_stop) 184*4882a593Smuzhiyun-{ 185*4882a593Smuzhiyun- enum __codecvt_result result; 186*4882a593Smuzhiyun- 187*4882a593Smuzhiyun- struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; 188*4882a593Smuzhiyun- int status; 189*4882a593Smuzhiyun- size_t dummy; 190*4882a593Smuzhiyun- 191*4882a593Smuzhiyun- codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start; 192*4882a593Smuzhiyun- codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end; 193*4882a593Smuzhiyun- codecvt->__cd_out.__cd.__data[0].__statep = statep; 194*4882a593Smuzhiyun- 195*4882a593Smuzhiyun- __gconv_fct fct = gs->__fct; 196*4882a593Smuzhiyun-#ifdef PTR_DEMANGLE 197*4882a593Smuzhiyun- if (gs->__shlib_handle != NULL) 198*4882a593Smuzhiyun- PTR_DEMANGLE (fct); 199*4882a593Smuzhiyun-#endif 200*4882a593Smuzhiyun- 201*4882a593Smuzhiyun- status = DL_CALL_FCT (fct, 202*4882a593Smuzhiyun- (gs, codecvt->__cd_out.__cd.__data, NULL, NULL, 203*4882a593Smuzhiyun- NULL, &dummy, 1, 0)); 204*4882a593Smuzhiyun- 205*4882a593Smuzhiyun- *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf; 206*4882a593Smuzhiyun- 207*4882a593Smuzhiyun- switch (status) 208*4882a593Smuzhiyun- { 209*4882a593Smuzhiyun- case __GCONV_OK: 210*4882a593Smuzhiyun- case __GCONV_EMPTY_INPUT: 211*4882a593Smuzhiyun- result = __codecvt_ok; 212*4882a593Smuzhiyun- break; 213*4882a593Smuzhiyun- 214*4882a593Smuzhiyun- case __GCONV_FULL_OUTPUT: 215*4882a593Smuzhiyun- case __GCONV_INCOMPLETE_INPUT: 216*4882a593Smuzhiyun- result = __codecvt_partial; 217*4882a593Smuzhiyun- break; 218*4882a593Smuzhiyun- 219*4882a593Smuzhiyun- default: 220*4882a593Smuzhiyun- result = __codecvt_error; 221*4882a593Smuzhiyun- break; 222*4882a593Smuzhiyun- } 223*4882a593Smuzhiyun- 224*4882a593Smuzhiyun- return result; 225*4882a593Smuzhiyun-} 226*4882a593Smuzhiyun- 227*4882a593Smuzhiyun- 228*4882a593Smuzhiyun-static enum __codecvt_result 229*4882a593Smuzhiyun-do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, 230*4882a593Smuzhiyun- const char *from_start, const char *from_end, const char **from_stop, 231*4882a593Smuzhiyun- wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) 232*4882a593Smuzhiyun+enum __codecvt_result 233*4882a593Smuzhiyun+__libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, 234*4882a593Smuzhiyun+ const char *from_start, const char *from_end, 235*4882a593Smuzhiyun+ const char **from_stop, 236*4882a593Smuzhiyun+ wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop) 237*4882a593Smuzhiyun { 238*4882a593Smuzhiyun enum __codecvt_result result; 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun@@ -301,8 +214,8 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, 241*4882a593Smuzhiyun } 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun-static int 245*4882a593Smuzhiyun-do_encoding (struct _IO_codecvt *codecvt) 246*4882a593Smuzhiyun+int 247*4882a593Smuzhiyun+__libio_codecvt_encoding (struct _IO_codecvt *codecvt) 248*4882a593Smuzhiyun { 249*4882a593Smuzhiyun /* See whether the encoding is stateful. */ 250*4882a593Smuzhiyun if (codecvt->__cd_in.__cd.__steps[0].__stateful) 251*4882a593Smuzhiyun@@ -318,16 +231,10 @@ do_encoding (struct _IO_codecvt *codecvt) 252*4882a593Smuzhiyun } 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun-static int 256*4882a593Smuzhiyun-do_always_noconv (struct _IO_codecvt *codecvt) 257*4882a593Smuzhiyun-{ 258*4882a593Smuzhiyun- return 0; 259*4882a593Smuzhiyun-} 260*4882a593Smuzhiyun- 261*4882a593Smuzhiyun- 262*4882a593Smuzhiyun-static int 263*4882a593Smuzhiyun-do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, 264*4882a593Smuzhiyun- const char *from_start, const char *from_end, size_t max) 265*4882a593Smuzhiyun+int 266*4882a593Smuzhiyun+__libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, 267*4882a593Smuzhiyun+ const char *from_start, const char *from_end, 268*4882a593Smuzhiyun+ size_t max) 269*4882a593Smuzhiyun { 270*4882a593Smuzhiyun int result; 271*4882a593Smuzhiyun const unsigned char *cp = (const unsigned char *) from_start; 272*4882a593Smuzhiyun@@ -354,10 +261,3 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun return result; 275*4882a593Smuzhiyun } 276*4882a593Smuzhiyun- 277*4882a593Smuzhiyun- 278*4882a593Smuzhiyun-static int 279*4882a593Smuzhiyun-do_max_length (struct _IO_codecvt *codecvt) 280*4882a593Smuzhiyun-{ 281*4882a593Smuzhiyun- return codecvt->__cd_in.__cd.__steps[0].__max_needed_from; 282*4882a593Smuzhiyun-} 283*4882a593Smuzhiyundiff --git a/libio/libio.h b/libio/libio.h 284*4882a593Smuzhiyunindex 00f91696..5291bb8d 100644 285*4882a593Smuzhiyun--- a/libio/libio.h 286*4882a593Smuzhiyun+++ b/libio/libio.h 287*4882a593Smuzhiyun@@ -118,40 +118,8 @@ struct _IO_marker { 288*4882a593Smuzhiyun int _pos; 289*4882a593Smuzhiyun }; 290*4882a593Smuzhiyun 291*4882a593Smuzhiyun-/* This is the structure from the libstdc++ codecvt class. */ 292*4882a593Smuzhiyun-enum __codecvt_result 293*4882a593Smuzhiyun-{ 294*4882a593Smuzhiyun- __codecvt_ok, 295*4882a593Smuzhiyun- __codecvt_partial, 296*4882a593Smuzhiyun- __codecvt_error, 297*4882a593Smuzhiyun- __codecvt_noconv 298*4882a593Smuzhiyun-}; 299*4882a593Smuzhiyun- 300*4882a593Smuzhiyun-/* The order of the elements in the following struct must match the order 301*4882a593Smuzhiyun- of the virtual functions in the libstdc++ codecvt class. */ 302*4882a593Smuzhiyun struct _IO_codecvt 303*4882a593Smuzhiyun { 304*4882a593Smuzhiyun- void (*__codecvt_destr) (struct _IO_codecvt *); 305*4882a593Smuzhiyun- enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *, 306*4882a593Smuzhiyun- __mbstate_t *, 307*4882a593Smuzhiyun- const wchar_t *, 308*4882a593Smuzhiyun- const wchar_t *, 309*4882a593Smuzhiyun- const wchar_t **, char *, 310*4882a593Smuzhiyun- char *, char **); 311*4882a593Smuzhiyun- enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *, 312*4882a593Smuzhiyun- __mbstate_t *, char *, 313*4882a593Smuzhiyun- char *, char **); 314*4882a593Smuzhiyun- enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *, 315*4882a593Smuzhiyun- __mbstate_t *, 316*4882a593Smuzhiyun- const char *, const char *, 317*4882a593Smuzhiyun- const char **, wchar_t *, 318*4882a593Smuzhiyun- wchar_t *, wchar_t **); 319*4882a593Smuzhiyun- int (*__codecvt_do_encoding) (struct _IO_codecvt *); 320*4882a593Smuzhiyun- int (*__codecvt_do_always_noconv) (struct _IO_codecvt *); 321*4882a593Smuzhiyun- int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *, 322*4882a593Smuzhiyun- const char *, const char *, size_t); 323*4882a593Smuzhiyun- int (*__codecvt_do_max_length) (struct _IO_codecvt *); 324*4882a593Smuzhiyun- 325*4882a593Smuzhiyun _IO_iconv_t __cd_in; 326*4882a593Smuzhiyun _IO_iconv_t __cd_out; 327*4882a593Smuzhiyun }; 328*4882a593Smuzhiyundiff --git a/libio/libioP.h b/libio/libioP.h 329*4882a593Smuzhiyunindex df2633d8..7ee71a63 100644 330*4882a593Smuzhiyun--- a/libio/libioP.h 331*4882a593Smuzhiyun+++ b/libio/libioP.h 332*4882a593Smuzhiyun@@ -476,7 +476,6 @@ extern const struct _IO_jump_t _IO_streambuf_jumps; 333*4882a593Smuzhiyun extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden; 334*4882a593Smuzhiyun extern const struct _IO_jump_t _IO_str_jumps attribute_hidden; 335*4882a593Smuzhiyun extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden; 336*4882a593Smuzhiyun-extern const struct _IO_codecvt __libio_codecvt attribute_hidden; 337*4882a593Smuzhiyun extern int _IO_do_write (FILE *, const char *, size_t); 338*4882a593Smuzhiyun libc_hidden_proto (_IO_do_write) 339*4882a593Smuzhiyun extern int _IO_new_do_write (FILE *, const char *, size_t); 340*4882a593Smuzhiyun@@ -839,4 +838,32 @@ IO_validate_vtable (const struct _IO_jump_t *vtable) 341*4882a593Smuzhiyun return vtable; 342*4882a593Smuzhiyun } 343*4882a593Smuzhiyun 344*4882a593Smuzhiyun+/* Character set conversion. */ 345*4882a593Smuzhiyun+ 346*4882a593Smuzhiyun+enum __codecvt_result 347*4882a593Smuzhiyun+{ 348*4882a593Smuzhiyun+ __codecvt_ok, 349*4882a593Smuzhiyun+ __codecvt_partial, 350*4882a593Smuzhiyun+ __codecvt_error, 351*4882a593Smuzhiyun+ __codecvt_noconv 352*4882a593Smuzhiyun+}; 353*4882a593Smuzhiyun+ 354*4882a593Smuzhiyun+enum __codecvt_result __libio_codecvt_out (struct _IO_codecvt *, 355*4882a593Smuzhiyun+ __mbstate_t *, 356*4882a593Smuzhiyun+ const wchar_t *, 357*4882a593Smuzhiyun+ const wchar_t *, 358*4882a593Smuzhiyun+ const wchar_t **, char *, 359*4882a593Smuzhiyun+ char *, char **) 360*4882a593Smuzhiyun+ attribute_hidden; 361*4882a593Smuzhiyun+enum __codecvt_result __libio_codecvt_in (struct _IO_codecvt *, 362*4882a593Smuzhiyun+ __mbstate_t *, 363*4882a593Smuzhiyun+ const char *, const char *, 364*4882a593Smuzhiyun+ const char **, wchar_t *, 365*4882a593Smuzhiyun+ wchar_t *, wchar_t **) 366*4882a593Smuzhiyun+ attribute_hidden; 367*4882a593Smuzhiyun+int __libio_codecvt_encoding (struct _IO_codecvt *) attribute_hidden; 368*4882a593Smuzhiyun+int __libio_codecvt_length (struct _IO_codecvt *, __mbstate_t *, 369*4882a593Smuzhiyun+ const char *, const char *, size_t) 370*4882a593Smuzhiyun+ attribute_hidden; 371*4882a593Smuzhiyun+ 372*4882a593Smuzhiyun #endif /* libioP.h. */ 373*4882a593Smuzhiyundiff --git a/libio/wfileops.c b/libio/wfileops.c 374*4882a593Smuzhiyunindex 63cb6876..ddc96295 100644 375*4882a593Smuzhiyun--- a/libio/wfileops.c 376*4882a593Smuzhiyun+++ b/libio/wfileops.c 377*4882a593Smuzhiyun@@ -72,11 +72,11 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do) 378*4882a593Smuzhiyun } 379*4882a593Smuzhiyun 380*4882a593Smuzhiyun /* Now convert from the internal format into the external buffer. */ 381*4882a593Smuzhiyun- result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state, 382*4882a593Smuzhiyun- data, data + to_do, &new_data, 383*4882a593Smuzhiyun- write_ptr, 384*4882a593Smuzhiyun- buf_end, 385*4882a593Smuzhiyun- &write_ptr); 386*4882a593Smuzhiyun+ result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state, 387*4882a593Smuzhiyun+ data, data + to_do, &new_data, 388*4882a593Smuzhiyun+ write_ptr, 389*4882a593Smuzhiyun+ buf_end, 390*4882a593Smuzhiyun+ &write_ptr); 391*4882a593Smuzhiyun 392*4882a593Smuzhiyun /* Write out what we produced so far. */ 393*4882a593Smuzhiyun if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF) 394*4882a593Smuzhiyun@@ -140,12 +140,12 @@ _IO_wfile_underflow (FILE *fp) 395*4882a593Smuzhiyun fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; 396*4882a593Smuzhiyun fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = 397*4882a593Smuzhiyun fp->_wide_data->_IO_buf_base; 398*4882a593Smuzhiyun- status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, 399*4882a593Smuzhiyun- fp->_IO_read_ptr, fp->_IO_read_end, 400*4882a593Smuzhiyun- &read_stop, 401*4882a593Smuzhiyun- fp->_wide_data->_IO_read_ptr, 402*4882a593Smuzhiyun- fp->_wide_data->_IO_buf_end, 403*4882a593Smuzhiyun- &fp->_wide_data->_IO_read_end); 404*4882a593Smuzhiyun+ status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, 405*4882a593Smuzhiyun+ fp->_IO_read_ptr, fp->_IO_read_end, 406*4882a593Smuzhiyun+ &read_stop, 407*4882a593Smuzhiyun+ fp->_wide_data->_IO_read_ptr, 408*4882a593Smuzhiyun+ fp->_wide_data->_IO_buf_end, 409*4882a593Smuzhiyun+ &fp->_wide_data->_IO_read_end); 410*4882a593Smuzhiyun 411*4882a593Smuzhiyun fp->_IO_read_base = fp->_IO_read_ptr; 412*4882a593Smuzhiyun fp->_IO_read_ptr = (char *) read_stop; 413*4882a593Smuzhiyun@@ -266,11 +266,11 @@ _IO_wfile_underflow (FILE *fp) 414*4882a593Smuzhiyun naccbuf += to_copy; 415*4882a593Smuzhiyun from = accbuf; 416*4882a593Smuzhiyun } 417*4882a593Smuzhiyun- status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, 418*4882a593Smuzhiyun- from, to, &read_ptr_copy, 419*4882a593Smuzhiyun- fp->_wide_data->_IO_read_end, 420*4882a593Smuzhiyun- fp->_wide_data->_IO_buf_end, 421*4882a593Smuzhiyun- &fp->_wide_data->_IO_read_end); 422*4882a593Smuzhiyun+ status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, 423*4882a593Smuzhiyun+ from, to, &read_ptr_copy, 424*4882a593Smuzhiyun+ fp->_wide_data->_IO_read_end, 425*4882a593Smuzhiyun+ fp->_wide_data->_IO_buf_end, 426*4882a593Smuzhiyun+ &fp->_wide_data->_IO_read_end); 427*4882a593Smuzhiyun 428*4882a593Smuzhiyun if (__glibc_unlikely (naccbuf != 0)) 429*4882a593Smuzhiyun fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]); 430*4882a593Smuzhiyun@@ -372,12 +372,12 @@ _IO_wfile_underflow_mmap (FILE *fp) 431*4882a593Smuzhiyun fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; 432*4882a593Smuzhiyun fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = 433*4882a593Smuzhiyun fp->_wide_data->_IO_buf_base; 434*4882a593Smuzhiyun- (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, 435*4882a593Smuzhiyun- fp->_IO_read_ptr, fp->_IO_read_end, 436*4882a593Smuzhiyun- &read_stop, 437*4882a593Smuzhiyun- fp->_wide_data->_IO_read_ptr, 438*4882a593Smuzhiyun- fp->_wide_data->_IO_buf_end, 439*4882a593Smuzhiyun- &fp->_wide_data->_IO_read_end); 440*4882a593Smuzhiyun+ __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, 441*4882a593Smuzhiyun+ fp->_IO_read_ptr, fp->_IO_read_end, 442*4882a593Smuzhiyun+ &read_stop, 443*4882a593Smuzhiyun+ fp->_wide_data->_IO_read_ptr, 444*4882a593Smuzhiyun+ fp->_wide_data->_IO_buf_end, 445*4882a593Smuzhiyun+ &fp->_wide_data->_IO_read_end); 446*4882a593Smuzhiyun 447*4882a593Smuzhiyun fp->_IO_read_ptr = (char *) read_stop; 448*4882a593Smuzhiyun 449*4882a593Smuzhiyun@@ -495,7 +495,7 @@ _IO_wfile_sync (FILE *fp) 450*4882a593Smuzhiyun struct _IO_codecvt *cv = fp->_codecvt; 451*4882a593Smuzhiyun off64_t new_pos; 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun- int clen = (*cv->__codecvt_do_encoding) (cv); 454*4882a593Smuzhiyun+ int clen = __libio_codecvt_encoding (cv); 455*4882a593Smuzhiyun 456*4882a593Smuzhiyun if (clen > 0) 457*4882a593Smuzhiyun /* It is easy, a fixed number of input bytes are used for each 458*4882a593Smuzhiyun@@ -510,9 +510,9 @@ _IO_wfile_sync (FILE *fp) 459*4882a593Smuzhiyun int nread; 460*4882a593Smuzhiyun 461*4882a593Smuzhiyun fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; 462*4882a593Smuzhiyun- nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, 463*4882a593Smuzhiyun- fp->_IO_read_base, 464*4882a593Smuzhiyun- fp->_IO_read_end, delta); 465*4882a593Smuzhiyun+ nread = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state, 466*4882a593Smuzhiyun+ fp->_IO_read_base, 467*4882a593Smuzhiyun+ fp->_IO_read_end, delta); 468*4882a593Smuzhiyun fp->_IO_read_ptr = fp->_IO_read_base + nread; 469*4882a593Smuzhiyun delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); 470*4882a593Smuzhiyun } 471*4882a593Smuzhiyun@@ -547,7 +547,7 @@ adjust_wide_data (FILE *fp, bool do_convert) 472*4882a593Smuzhiyun { 473*4882a593Smuzhiyun struct _IO_codecvt *cv = fp->_codecvt; 474*4882a593Smuzhiyun 475*4882a593Smuzhiyun- int clen = (*cv->__codecvt_do_encoding) (cv); 476*4882a593Smuzhiyun+ int clen = __libio_codecvt_encoding (cv); 477*4882a593Smuzhiyun 478*4882a593Smuzhiyun /* Take the easy way out for constant length encodings if we don't need to 479*4882a593Smuzhiyun convert. */ 480*4882a593Smuzhiyun@@ -564,12 +564,12 @@ adjust_wide_data (FILE *fp, bool do_convert) 481*4882a593Smuzhiyun { 482*4882a593Smuzhiyun 483*4882a593Smuzhiyun fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; 484*4882a593Smuzhiyun- status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state, 485*4882a593Smuzhiyun- fp->_IO_read_base, fp->_IO_read_ptr, 486*4882a593Smuzhiyun- &read_stop, 487*4882a593Smuzhiyun- fp->_wide_data->_IO_read_base, 488*4882a593Smuzhiyun- fp->_wide_data->_IO_buf_end, 489*4882a593Smuzhiyun- &fp->_wide_data->_IO_read_end); 490*4882a593Smuzhiyun+ status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state, 491*4882a593Smuzhiyun+ fp->_IO_read_base, fp->_IO_read_ptr, 492*4882a593Smuzhiyun+ &read_stop, 493*4882a593Smuzhiyun+ fp->_wide_data->_IO_read_base, 494*4882a593Smuzhiyun+ fp->_wide_data->_IO_buf_end, 495*4882a593Smuzhiyun+ &fp->_wide_data->_IO_read_end); 496*4882a593Smuzhiyun 497*4882a593Smuzhiyun /* Should we return EILSEQ? */ 498*4882a593Smuzhiyun if (__glibc_unlikely (status == __codecvt_error)) 499*4882a593Smuzhiyun@@ -647,7 +647,7 @@ do_ftell_wide (FILE *fp) 500*4882a593Smuzhiyun } 501*4882a593Smuzhiyun 502*4882a593Smuzhiyun struct _IO_codecvt *cv = fp->_codecvt; 503*4882a593Smuzhiyun- int clen = (*cv->__codecvt_do_encoding) (cv); 504*4882a593Smuzhiyun+ int clen = __libio_codecvt_encoding (cv); 505*4882a593Smuzhiyun 506*4882a593Smuzhiyun if (!unflushed_writes) 507*4882a593Smuzhiyun { 508*4882a593Smuzhiyun@@ -662,9 +662,9 @@ do_ftell_wide (FILE *fp) 509*4882a593Smuzhiyun 510*4882a593Smuzhiyun size_t delta = wide_read_ptr - wide_read_base; 511*4882a593Smuzhiyun __mbstate_t state = fp->_wide_data->_IO_last_state; 512*4882a593Smuzhiyun- nread = (*cv->__codecvt_do_length) (cv, &state, 513*4882a593Smuzhiyun- fp->_IO_read_base, 514*4882a593Smuzhiyun- fp->_IO_read_end, delta); 515*4882a593Smuzhiyun+ nread = __libio_codecvt_length (cv, &state, 516*4882a593Smuzhiyun+ fp->_IO_read_base, 517*4882a593Smuzhiyun+ fp->_IO_read_end, delta); 518*4882a593Smuzhiyun offset -= fp->_IO_read_end - fp->_IO_read_base - nread; 519*4882a593Smuzhiyun } 520*4882a593Smuzhiyun } 521*4882a593Smuzhiyun@@ -687,9 +687,8 @@ do_ftell_wide (FILE *fp) 522*4882a593Smuzhiyun enum __codecvt_result status; 523*4882a593Smuzhiyun 524*4882a593Smuzhiyun __mbstate_t state = fp->_wide_data->_IO_last_state; 525*4882a593Smuzhiyun- status = (*cv->__codecvt_do_out) (cv, &state, 526*4882a593Smuzhiyun- in, in + delta, &in, 527*4882a593Smuzhiyun- out, out + outsize, &outstop); 528*4882a593Smuzhiyun+ status = __libio_codecvt_out (cv, &state, in, in + delta, &in, 529*4882a593Smuzhiyun+ out, out + outsize, &outstop); 530*4882a593Smuzhiyun 531*4882a593Smuzhiyun /* We don't check for __codecvt_partial because it can be 532*4882a593Smuzhiyun returned on one of two conditions: either the output 533*4882a593Smuzhiyun@@ -800,7 +799,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) 534*4882a593Smuzhiyun find out which position in the external buffer corresponds to 535*4882a593Smuzhiyun the current position in the internal buffer. */ 536*4882a593Smuzhiyun cv = fp->_codecvt; 537*4882a593Smuzhiyun- clen = (*cv->__codecvt_do_encoding) (cv); 538*4882a593Smuzhiyun+ clen = __libio_codecvt_encoding (cv); 539*4882a593Smuzhiyun 540*4882a593Smuzhiyun if (mode != 0 || !was_writing) 541*4882a593Smuzhiyun { 542*4882a593Smuzhiyun@@ -818,10 +817,10 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) 543*4882a593Smuzhiyun delta = (fp->_wide_data->_IO_read_ptr 544*4882a593Smuzhiyun - fp->_wide_data->_IO_read_base); 545*4882a593Smuzhiyun fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; 546*4882a593Smuzhiyun- nread = (*cv->__codecvt_do_length) (cv, 547*4882a593Smuzhiyun- &fp->_wide_data->_IO_state, 548*4882a593Smuzhiyun- fp->_IO_read_base, 549*4882a593Smuzhiyun- fp->_IO_read_end, delta); 550*4882a593Smuzhiyun+ nread = __libio_codecvt_length (cv, 551*4882a593Smuzhiyun+ &fp->_wide_data->_IO_state, 552*4882a593Smuzhiyun+ fp->_IO_read_base, 553*4882a593Smuzhiyun+ fp->_IO_read_end, delta); 554*4882a593Smuzhiyun fp->_IO_read_ptr = fp->_IO_read_base + nread; 555*4882a593Smuzhiyun fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; 556*4882a593Smuzhiyun offset -= fp->_IO_read_end - fp->_IO_read_base - nread; 557*4882a593Smuzhiyun-- 558*4882a593Smuzhiyun2.20.1 559*4882a593Smuzhiyun 560