patch-2.4.0-test5 linux/fs/ncpfs/ncplib_kernel.c
Next file: linux/fs/nfsd/auth.c
Previous file: linux/fs/namei.c
Back to the patch index
Back to the overall index
- Lines: 240
- Date:
Tue Jul 18 22:48:32 2000
- Orig file:
v2.4.0-test4/linux/fs/ncpfs/ncplib_kernel.c
- Orig date:
Mon Jul 10 16:47:26 2000
diff -u --recursive --new-file v2.4.0-test4/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
@@ -916,73 +916,73 @@
{
struct nls_table *in = server->nls_io;
struct nls_table *out = server->nls_vol;
- struct nls_unicode uc;
- unsigned char nc, *up;
- int i, k, maxlen = *vlen - 1;
- __u16 ec;
-
- *vlen = 0;
-
- for (i = 0; i < ilen;) {
- if (*vlen == maxlen)
- return -ENAMETOOLONG;
+ unsigned char *vname_start;
+ unsigned char *vname_end;
+ const unsigned char *iname_end;
+
+ iname_end = iname + ilen;
+ vname_start = vname;
+ vname_end = vname + *vlen - 1;
+
+ while (iname < iname_end) {
+ int chl;
+ wchar_t ec;
if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) {
- k = utf8_mbtowc(&ec, iname, ilen - i);
- if (k == -1)
+ int k;
+
+ k = utf8_mbtowc(&ec, iname, iname_end - iname);
+ if (k < 0)
return -EINVAL;
- uc.uni1 = ec & 0xFF;
- uc.uni2 = ec >> 8;
iname += k;
- i += k;
} else {
if (*iname == NCP_ESC) {
- if (i > ilen - 5)
- return -EINVAL;
+ int k;
+
+ if (iname_end - iname < 5)
+ goto nospec;
ec = 0;
for (k = 1; k < 5; k++) {
- nc = iname[k];
- ec <<= 4;
- if (nc >= '0' && nc <= '9') {
- ec |= nc - '0';
- continue;
- }
- if (nc >= 'a' && nc <= 'f') {
- ec |= nc - ('a' - 10);
- continue;
- }
- if (nc >= 'A' && nc <= 'F') {
- ec |= nc - ('A' - 10);
- continue;
+ unsigned char nc;
+
+ nc = iname[k] - '0';
+ if (nc >= 10) {
+ nc -= 'A' - '0' - 10;
+ if ((nc < 10) || (nc > 15)) {
+ goto nospec;
+ }
}
- return -EINVAL;
+ ec = (ec << 4) | nc;
}
- uc.uni1 = ec & 0xFF;
- uc.uni2 = ec >> 8;
iname += 5;
- i += 5;
} else {
- uc = in->charset2uni[*iname];
- iname++;
- i++;
+nospec:;
+ if ( (chl = in->char2uni(iname, iname_end - iname, &ec)) < 0)
+ return chl;
+ iname += chl;
}
}
- up = out->page_uni2charset[uc.uni2];
- if (!up)
- return -EINVAL;
-
- nc = up[uc.uni1];
- if (!nc)
- return -EINVAL;
-
- *vname = cc ? ncp_toupper(out, nc) : nc;
- vname++;
- *vlen += 1;
+ /* unitoupper should be here! */
+
+ chl = out->uni2char(ec, vname, vname_end - vname);
+ if (chl < 0)
+ return chl;
+
+ /* this is wrong... */
+ if (cc) {
+ int chi;
+
+ for (chi = 0; chi < chl; chi++){
+ vname[chi] = ncp_toupper(out, vname[chi]);
+ }
+ }
+ vname += chl;
}
*vname = 0;
+ *vlen = vname - vname_start;
return 0;
}
@@ -992,57 +992,82 @@
{
struct nls_table *in = server->nls_vol;
struct nls_table *out = server->nls_io;
- struct nls_unicode uc;
- unsigned char nc, *up;
- int i, k, maxlen = *ilen - 1;
- __u16 ec;
-
- *ilen = 0;
-
- for (i = 0; i < vlen; i++) {
- if (*ilen == maxlen)
- return -ENAMETOOLONG;
+ const unsigned char *vname_end;
+ unsigned char *iname_start;
+ unsigned char *iname_end;
+ unsigned char *vname_cc;
+ int err;
+
+ vname_cc = NULL;
+
+ if (cc) {
+ int i;
+
+ /* this is wrong! */
+ vname_cc = kmalloc(vlen, GFP_KERNEL);
+ for (i = 0; i < vlen; i++)
+ vname_cc[i] = ncp_tolower(in, vname[i]);
+ vname = vname_cc;
+ }
+
+ iname_start = iname;
+ iname_end = iname + *ilen - 1;
+ vname_end = vname + vlen;
+
+ while (vname < vname_end) {
+ wchar_t ec;
+ int chl;
+
+ if ( (chl = in->char2uni(vname, vname_end - vname, &ec)) < 0) {
+ err = chl;
+ goto quit;
+ }
+ vname += chl;
- uc = in->charset2uni[cc ? ncp_tolower(in, *vname) : *vname];
+ /* unitolower should be here! */
if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) {
- k = utf8_wctomb(iname, (uc.uni2 << 8) + uc.uni1,
- maxlen - *ilen);
- if (k == -1)
- return -ENAMETOOLONG;
+ int k;
+
+ k = utf8_wctomb(iname, ec, iname_end - iname);
+ if (k < 0) {
+ err = -ENAMETOOLONG;
+ goto quit;
+ }
iname += k;
- *ilen += k;
} else {
- up = out->page_uni2charset[uc.uni2];
- if (up)
- nc = up[uc.uni1];
- else
- nc = 0;
-
- if (nc) {
- *iname = nc;
- iname++;
- *ilen += 1;
+ if ( (chl = out->uni2char(ec, iname, iname_end - iname)) >= 0) {
+ iname += chl;
} else {
- if (*ilen > maxlen - 5)
- return -ENAMETOOLONG;
- ec = (uc.uni2 << 8) + uc.uni1;
+ int k;
+
+ if (iname_end - iname < 5) {
+ err = -ENAMETOOLONG;
+ goto quit;
+ }
*iname = NCP_ESC;
for (k = 4; k > 0; k--) {
- nc = ec & 0xF;
- iname[k] = nc > 9 ? nc + ('a' - 10)
- : nc + '0';
+ unsigned char v;
+
+ v = (ec & 0xF) + '0';
+ if (v > '9') {
+ v += 'A' - '9' - 1;
+ }
+ iname[k] = v;
ec >>= 4;
}
iname += 5;
- *ilen += 5;
}
}
- vname++;
}
*iname = 0;
- return 0;
+ *ilen = iname - iname_start;
+ err = 0;
+quit:;
+ if (cc)
+ kfree(vname_cc);
+ return err;
}
#else
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)