View | Details | Raw Unified | Return to bug 133174
Collapse All | Expand All

(-)msdosfs.mew/msdosfs_conv.c (-16 / +140 lines)
Lines 63-69 extern struct iconv_functions *msdosfs_i Link Here
63
static int mbsadjpos(const char **, size_t, size_t, int, int, void *handle);
63
static int mbsadjpos(const char **, size_t, size_t, int, int, void *handle);
64
static u_int16_t dos2unixchr(const u_char **, size_t *, int, struct msdosfsmount *);
64
static u_int16_t dos2unixchr(const u_char **, size_t *, int, struct msdosfsmount *);
65
static u_int16_t unix2doschr(const u_char **, size_t *, struct msdosfsmount *);
65
static u_int16_t unix2doschr(const u_char **, size_t *, struct msdosfsmount *);
66
static u_int16_t win2unixchr(u_int16_t, struct msdosfsmount *);
66
static u_int32_t win2unixchr(u_int16_t, struct msdosfsmount *);
67
static u_int16_t unix2winchr(const u_char **, size_t *, int, struct msdosfsmount *);
67
static u_int16_t unix2winchr(const u_char **, size_t *, int, struct msdosfsmount *);
68
68
69
/*
69
/*
Lines 221-226 l2u[256] = { Link Here
221
	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */
221
	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* f8-ff */
222
};
222
};
223
223
224
static int iconv_u2w(const char **inbuf, size_t *inbytes,
225
        char **outbuf, size_t *outbytes)
226
{
227
    u_int8_t mark;
228
    u_int16_t uc = 0;
229
    char * obuf  = NULL;
230
    const char *ibuf, *ibuf_end, *obuf_end;
231
    if ((inbuf && inbytes && outbuf && outbytes)
232
            && (*inbuf && *inbytes && *outbuf && *outbytes)) {
233
        ibuf = *inbuf;
234
        ibuf_end = *inbuf + *inbytes;
235
        obuf = *outbuf;
236
        obuf_end = *outbuf + *outbytes;
237
        int follow = 0;
238
        while (ibuf < ibuf_end && &obuf[1] < obuf_end) {
239
            mark = (u_int8_t)*ibuf++;
240
            if (mark < 0xF0 && mark > 0xE0) {
241
                /* 1110XXXX */
242
                uc = mark & 0x0F;
243
                follow = 2;
244
            } else if (mark < 0xE0 && mark > 0xC0) {
245
                /* 110XXXXX */
246
                uc = mark & 0x1F;
247
                follow = 1;
248
            } else if (mark < 0x80) {
249
                /* 0XXXXXXX */
250
                uc = mark;
251
                follow = 0;
252
            } else {
253
                /* convert fail: 0xF0 0xE0 should NOT be in UTF-8 seq */
254
                printf("convert fail 0xF0 0xE0\n");
255
                break;
256
            }
257
            if (&ibuf[follow] > ibuf_end) {
258
                /* unexpected end of input */
259
                break;
260
            }
261
            for (; follow > 0; follow--) {
262
                /* 10XX.XXXX 0x80-0xBF */
263
                if ((*ibuf&0xC0) != 0x80) {
264
                    *outbytes = obuf_end - *outbuf;
265
                    *inbytes = ibuf_end - *inbuf;
266
                    printf("convert fail SEQ\n");
267
                    return (0);
268
                }
269
                uc = (uc << 6) | (*ibuf++ & 0x3F);
270
            }
271
            *obuf++ = (uc >> 8);
272
            *obuf++ = uc;
273
            *outbuf = obuf;
274
            *inbuf = ibuf;
275
        }
276
        *outbytes = obuf_end - *outbuf;
277
        *inbytes = ibuf_end - *inbuf;
278
    }
279
    return (0);
280
}
281
282
static int iconv_w2u(const char **inbuf, size_t *inbytes,
283
        char **outbuf, size_t *outbytes)
284
{
285
    u_int16_t uc = 0;
286
    char *obuf  = NULL;
287
    const char *ibuf, *ibuf_end, *obuf_end;
288
    if ((inbuf && inbytes && outbuf && outbytes)
289
            && (*inbuf && *inbytes && *outbuf && *outbytes)) {
290
        ibuf = *inbuf;
291
        ibuf_end = *inbuf+*inbytes;
292
        obuf = *outbuf;
293
        obuf_end = *outbuf+*outbytes;
294
        int follow = 0;
295
        while (&ibuf[1] < ibuf_end && obuf < obuf_end) {
296
            uc = (0xFF & *ibuf++);
297
            uc = (0xFF & *ibuf++) | (uc << 8);
298
            if (uc < 0x80) {
299
                *obuf++ = (uc);
300
                follow = 0;
301
            } else if (uc < 0x800) {
302
                *obuf++ = (uc >> 6) | 0xC0;
303
                follow = 1;
304
            } else {
305
                /* assert(uc <= 0xFFFF); */
306
                *obuf++ = (uc >> 12) | 0xE0;
307
                follow = 2;
308
            }
309
            if (&obuf[follow] > obuf_end) {
310
                /* no output buffer */
311
                break;
312
            }
313
            for (follow--; follow >= 0; follow--) {
314
                int shift = follow * 6;
315
                u_int8_t ch = uc >> shift;
316
                *obuf++ = (ch & 0x3F) | 0x80;
317
            }
318
            *outbuf = obuf;
319
            *inbuf = ibuf;
320
        }
321
        *outbytes = obuf_end - *outbuf;
322
        *inbytes = ibuf_end - *inbuf;
323
    }
324
    return (0);
325
}
326
224
/*
327
/*
225
 * DOS filenames are made of 2 parts, the name part and the extension part.
328
 * DOS filenames are made of 2 parts, the name part and the extension part.
226
 * The name part is 8 characters long and the extension part is 3
329
 * The name part is 8 characters long and the extension part is 3
Lines 653-660 win2unixfn(nbp, wep, chksum, pmp) Link Here
653
	struct msdosfsmount *pmp;
756
	struct msdosfsmount *pmp;
654
{
757
{
655
	u_int8_t *cp;
758
	u_int8_t *cp;
656
	u_int8_t *np, name[WIN_CHARS * 2 + 1];
759
	u_int8_t *np, name[WIN_CHARS * 3 + 1];
657
	u_int16_t code;
760
	u_int32_t code;
658
	int i;
761
	int i;
659
762
660
	if ((wep->weCnt & WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS)
763
	if ((wep->weCnt & WIN_CNT) > howmany(WIN_MAXLEN, WIN_CHARS)
Lines 687-692 win2unixfn(nbp, wep, chksum, pmp) Link Here
687
			return -1;
790
			return -1;
688
		default:
791
		default:
689
			code = win2unixchr(code, pmp);
792
			code = win2unixchr(code, pmp);
793
			if (code & 0xff0000)
794
				*np++ = code >> 16;
690
			if (code & 0xff00)
795
			if (code & 0xff00)
691
				*np++ = code >> 8;
796
				*np++ = code >> 8;
692
			*np++ = code;
797
			*np++ = code;
Lines 706-711 win2unixfn(nbp, wep, chksum, pmp) Link Here
706
			return -1;
811
			return -1;
707
		default:
812
		default:
708
			code = win2unixchr(code, pmp);
813
			code = win2unixchr(code, pmp);
814
			if (code & 0xff0000)
815
				*np++ = code >> 16;
709
			if (code & 0xff00)
816
			if (code & 0xff00)
710
				*np++ = code >> 8;
817
				*np++ = code >> 8;
711
			*np++ = code;
818
			*np++ = code;
Lines 725-730 win2unixfn(nbp, wep, chksum, pmp) Link Here
725
			return -1;
832
			return -1;
726
		default:
833
		default:
727
			code = win2unixchr(code, pmp);
834
			code = win2unixchr(code, pmp);
835
			if (code & 0xff0000)
836
				*np++ = code >> 16;
728
			if (code & 0xff00)
837
			if (code & 0xff00)
729
				*np++ = code >> 8;
838
				*np++ = code >> 8;
730
			*np++ = code;
839
			*np++ = code;
Lines 777-783 winSlotCnt(un, unlen, pmp) Link Here
777
	if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
886
	if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
778
		wlen = WIN_MAXLEN * 2;
887
		wlen = WIN_MAXLEN * 2;
779
		wnp = wn;
888
		wnp = wn;
780
		msdosfs_iconv->conv(pmp->pm_u2w, (const char **)&un, &unlen, &wnp, &wlen);
889
        if (pmp->pm_u2w != NULL)
890
            msdosfs_iconv->conv(pmp->pm_u2w, (const char **)&un, &unlen, &wnp, &wlen);
891
        else
892
            iconv_u2w((const char**)&un, &unlen, &wnp, &wlen);
781
		if (unlen > 0)
893
		if (unlen > 0)
782
			return 0;
894
			return 0;
783
		return howmany(WIN_MAXLEN - wlen/2, WIN_CHARS);
895
		return howmany(WIN_MAXLEN - wlen/2, WIN_CHARS);
Lines 815-821 mbsadjpos(const char **instr, size_t inl Link Here
815
	if (flag & MSDOSFSMNT_KICONV && msdosfs_iconv) {
927
	if (flag & MSDOSFSMNT_KICONV && msdosfs_iconv) {
816
		outp = outstr;
928
		outp = outstr;
817
		outlen *= weight;
929
		outlen *= weight;
818
		msdosfs_iconv->conv(handle, instr, &inlen, &outp, &outlen);
930
        if (handle != NULL)
931
            msdosfs_iconv->conv(handle, instr, &inlen, &outp, &outlen);
932
        else
933
            iconv_u2w(instr, &inlen, &outp, &outlen);
819
		return (inlen);
934
		return (inlen);
820
	}
935
	}
821
936
Lines 887-894 unix2doschr(const u_char **instr, size_t Link Here
887
		ucslen = 2;
1002
		ucslen = 2;
888
		len = *ilen;
1003
		len = *ilen;
889
		up = unicode;
1004
		up = unicode;
890
		msdosfs_iconv->convchr(pmp->pm_u2w, (const char **)instr,
1005
        if (pmp->pm_u2w != NULL)
891
				     ilen, &up, &ucslen);
1006
            msdosfs_iconv->convchr(pmp->pm_u2w, (const char **)instr,
1007
                    ilen, &up, &ucslen);
1008
        else
1009
            iconv_u2w((const char**)instr, ilen, &up, &ucslen);
892
		unixlen = len - *ilen;
1010
		unixlen = len - *ilen;
893
1011
894
		/*
1012
		/*
Lines 949-958 unix2doschr(const u_char **instr, size_t Link Here
949
/*
1067
/*
950
 * Convert Windows char to Local char
1068
 * Convert Windows char to Local char
951
 */
1069
 */
952
static u_int16_t
1070
static u_int32_t
953
win2unixchr(u_int16_t wc, struct msdosfsmount *pmp)
1071
win2unixchr(u_int16_t wc, struct msdosfsmount *pmp)
954
{
1072
{
955
	u_char *inp, *outp, inbuf[3], outbuf[3];
1073
	u_char *inp, *outp, inbuf[3], outbuf[4];
956
	size_t ilen, olen, len;
1074
	size_t ilen, olen, len;
957
1075
958
	if (wc == 0)
1076
	if (wc == 0)
Lines 964-973 win2unixchr(u_int16_t wc, struct msdosfs Link Here
964
		inbuf[2] = '\0';
1082
		inbuf[2] = '\0';
965
1083
966
		ilen = olen = len = 2;
1084
		ilen = olen = len = 2;
1085
        len = olen = 4;
967
		inp = inbuf;
1086
		inp = inbuf;
968
		outp = outbuf;
1087
		outp = outbuf;
969
		msdosfs_iconv->convchr(pmp->pm_w2u, (const char **)&inp, &ilen,
1088
        if (pmp->pm_w2u != NULL)
970
				     (char **)&outp, &olen);
1089
            msdosfs_iconv->convchr(pmp->pm_w2u, (const char **)&inp, &ilen,
1090
                    (char **)&outp, &olen);
1091
        else
1092
            iconv_w2u((const char**)&inp, &ilen, (char**)&outp, &olen);
971
		len -= olen;
1093
		len -= olen;
972
1094
973
		/*
1095
		/*
Lines 978-987 win2unixchr(u_int16_t wc, struct msdosfs Link Here
978
			return (wc);
1100
			return (wc);
979
		}
1101
		}
980
1102
981
		wc = 0;
1103
		u_int32_t wc32 = 0;
982
		while (len--)
1104
		while (len--)
983
			wc |= (*(outp - len - 1) & 0xff) << (len << 3);
1105
			wc32 |= (*(outp - len - 1) & 0xff) << (len << 3);
984
		return (wc);
1106
		return (wc32);
985
	}
1107
	}
986
1108
987
	if (wc & 0xff00)
1109
	if (wc & 0xff00)
Lines 1006-1012 unix2winchr(const u_char **instr, size_t Link Here
1006
	if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
1128
	if (pmp->pm_flags & MSDOSFSMNT_KICONV && msdosfs_iconv) {
1007
		outp = outbuf;
1129
		outp = outbuf;
1008
		olen = 2;
1130
		olen = 2;
1009
		if (lower & (LCASE_BASE | LCASE_EXT))
1131
        if (pmp->pm_u2w == NULL)
1132
            iconv_u2w((const char**)instr, ilen, (char **)&outp, &olen);
1133
        else if (lower & (LCASE_BASE | LCASE_EXT))
1010
			msdosfs_iconv->convchr_case(pmp->pm_u2w, (const char **)instr,
1134
			msdosfs_iconv->convchr_case(pmp->pm_u2w, (const char **)instr,
1011
						  ilen, (char **)&outp, &olen,
1135
						  ilen, (char **)&outp, &olen,
1012
						  KICONV_FROM_LOWER);
1136
						  KICONV_FROM_LOWER);
Lines 1020-1026 unix2winchr(const u_char **instr, size_t Link Here
1020
		if (olen == 2)
1144
		if (olen == 2)
1021
			return (0);
1145
			return (0);
1022
1146
1023
		wc = (outbuf[0]<<8) | outbuf[1];
1147
        wc = (outbuf[0] << 8) | outbuf[1];
1024
1148
1025
		return (wc);
1149
		return (wc);
1026
	}
1150
	}
(-)msdosfs.mew/msdosfs_vfsops.c (-4 / +12 lines)
Lines 131-140 update_mp(struct mount *mp, struct threa Link Here
131
				error = vfs_getopt(mp->mnt_optnew,
131
				error = vfs_getopt(mp->mnt_optnew,
132
				    "cs_dos", &dos, NULL);
132
				    "cs_dos", &dos, NULL);
133
			if (!error) {
133
			if (!error) {
134
				msdosfs_iconv->open(win, local, &pmp->pm_u2w);
134
                char *p = (char*)local;
135
				msdosfs_iconv->open(local, win, &pmp->pm_w2u);
135
                if (p != NULL && p[0] == 'U'
136
				msdosfs_iconv->open(dos, local, &pmp->pm_u2d);
136
                        && p[1] == 'T' && p[2] == 'F'
137
				msdosfs_iconv->open(local, dos, &pmp->pm_d2u);
137
                        && p[3] == '-' && p[4] == '8' && p[5] == '\0') {
138
                    pmp->pm_w2u = NULL;
139
                    pmp->pm_u2w = NULL;
140
                } else {
141
                    msdosfs_iconv->open(win, local, &pmp->pm_u2w);
142
                    msdosfs_iconv->open(local, win, &pmp->pm_w2u);
143
                }
144
                msdosfs_iconv->open(dos, local, &pmp->pm_u2d);
145
                msdosfs_iconv->open(local, dos, &pmp->pm_d2u);
138
			}
146
			}
139
			if (error != 0)
147
			if (error != 0)
140
				return (error);
148
				return (error);

Return to bug 133174