On Tue, Mar 30, 2004 at 07:05:22AM -0500, Jeff Trawick wrote: > [EMAIL PROTECTED] wrote: > >jorton 2004/03/30 01:58:22 > > > > Modified: xlate xlate.c > > Log: > > * xlate/xlate.c (check_sbcs): Remove function which made unsafe > > assumptions (a theoretical issue), and was buggy in not resetting the > > iconv handle on failure (the cause of at least one real issue). > > (apr_xlate_open): Updated caller. > > there is some additional work to be done with this... I have a patch to > yank apr_xlate_sb_get() and modify the various apr-util callers of it, but > probably won't get it committed until tonight or tomorrow a.m....
Yeah, I was going to commit the more radical changes separately... attached what I have. > apr-util 0.9 will mark the apr_xlate_sb_get() API deprecated, and of course > your fix to reset the iconv handle on failure needs to be in 0.9 Actually I thought that the simple removal of check_sbcs() would be appropriate for 0.9 too, rather than wait for someone to find a case where it "does the wrong thing". > additionally, the single-byte conversion routines need to be reworked to > not depend on the sbcs table, which now is purely an identity table which > is used when the to and from charsets are the same With just identity tables remaining, conv_byte is either a nullop or an error, so I removed it. But you did want to keep it around for a future where APR has hard-coded single-byte-lookup tables for some translations? > but then the identity table use, which was implemented to piggyback on the > sbcs "optimization," should be replaced with memcpy() ;) Indeed, makes it much simpler :) joe
Index: xlate/xlate.c =================================================================== RCS file: /home/cvs/apr-util/xlate/xlate.c,v retrieving revision 1.20 diff -u -r1.20 xlate.c --- xlate/xlate.c 30 Mar 2004 09:58:22 -0000 1.20 +++ xlate/xlate.c 30 Mar 2004 13:08:00 -0000 @@ -54,9 +54,7 @@ struct apr_xlate_t { apr_pool_t *pool; - char *frompage; - char *topage; - char *sbcs_table; + int identity; #if APU_HAVE_ICONV iconv_t ich; #elif APU_HAVE_APR_ICONV @@ -101,23 +99,12 @@ return APR_SUCCESS; } -static void make_identity_table(apr_xlate_t *convset) -{ - int i; - - convset->sbcs_table = apr_palloc(convset->pool, 256); - for (i = 0; i < 256; i++) - convset->sbcs_table[i] = i; -} - APU_DECLARE(apr_status_t) apr_xlate_open(apr_xlate_t **convset, const char *topage, const char *frompage, apr_pool_t *pool) { - apr_status_t rv; apr_xlate_t *new; - int found = 0; *convset = NULL; @@ -125,71 +112,43 @@ frompage = handle_special_names(frompage, pool); new = (apr_xlate_t *)apr_pcalloc(pool, sizeof(apr_xlate_t)); - if (!new) { - return APR_ENOMEM; - } - new->pool = pool; - new->topage = apr_pstrdup(pool, topage); - new->frompage = apr_pstrdup(pool, frompage); - if (!new->topage || !new->frompage) { - return APR_ENOMEM; - } #ifdef TODO /* search cache of codepage pairs; we may be able to avoid the - * expensive iconv_open() + * expensive iconv_open(). */ - - set found to non-zero if found in the cache #endif - - if ((! found) && (strcmp(topage, frompage) == 0)) { + + if (strcmp(topage, frompage) == 0) { /* to and from are the same */ - found = 1; - make_identity_table(new); + new->identity = 1; } - + else { #if APU_HAVE_APR_ICONV - if (!found) { rv = apr_iconv_open(topage, frompage, pool, &new->ich); if (rv != APR_SUCCESS) { return rv; } - found = 1; - } else - new->ich = (apr_iconv_t)-1; - #elif APU_HAVE_ICONV - if (!found) { new->ich = iconv_open(topage, frompage); if (new->ich == (iconv_t)-1) { int rv = errno; /* Sometimes, iconv is not good about setting errno. */ return rv ? rv : APR_EINVAL; } - found = 1; - } else - new->ich = (iconv_t)-1; #endif /* APU_HAVE_ICONV */ - - if (found) { - *convset = new; - apr_pool_cleanup_register(pool, (void *)new, apr_xlate_cleanup, - apr_pool_cleanup_null); - rv = APR_SUCCESS; + apr_pool_cleanup_register(pool, new, apr_xlate_cleanup, + apr_pool_cleanup_null); } - else { - rv = APR_EINVAL; /* iconv() would return EINVAL if it - couldn't handle the pair */ - } - - return rv; + + *convset = new; + return APR_SUCCESS; } APU_DECLARE(apr_status_t) apr_xlate_sb_get(apr_xlate_t *convset, int *onoff) { - *onoff = convset->sbcs_table != NULL; + *onoff = convset->identity; return APR_SUCCESS; } @@ -201,8 +160,18 @@ { apr_status_t status = APR_SUCCESS; + if (convset->identity) { + apr_size_t len = *inbytes_left; + + if (len > *outbytes_left) len = *outbytes_left; + + memcpy(outbuf, inbuf, len); + + *outbytes_left -= len; + *inbytes_left -= len; + } + else { #if APU_HAVE_APR_ICONV - if (convset->ich != (apr_iconv_t)-1) { const char *inbufptr = inbuf; apr_size_t translated; char *outbufptr = outbuf; @@ -245,11 +214,7 @@ default: break; } - } - else - #elif APU_HAVE_ICONV - if (convset->ich != (iconv_t)-1) { const char *inbufptr = inbuf; char *outbufptr = outbuf; apr_size_t translated; @@ -295,42 +260,18 @@ break; } } - } - else #endif - - { - int to_convert = min(*inbytes_left, *outbytes_left); - int converted = to_convert; - char *table = convset->sbcs_table; - - while (to_convert) { - *outbuf = table[(unsigned char)*inbuf]; - ++outbuf; - ++inbuf; - --to_convert; - } - *inbytes_left -= converted; - *outbytes_left -= converted; } return status; } -APU_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset, - unsigned char inchar) -{ - if (convset->sbcs_table) { - return convset->sbcs_table[inchar]; - } - else { - return -1; - } -} - APU_DECLARE(apr_status_t) apr_xlate_close(apr_xlate_t *convset) { - return apr_pool_cleanup_run(convset->pool, convset, apr_xlate_cleanup); + if (convset->identity) + return APR_SUCCESS; + else + return apr_pool_cleanup_run(convset->pool, convset, apr_xlate_cleanup); } #else /* !APR_HAS_XLATE */ @@ -346,12 +287,6 @@ APU_DECLARE(apr_status_t) apr_xlate_sb_get(apr_xlate_t *convset, int *onoff) { return APR_ENOTIMPL; -} - -APU_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset, - unsigned char inchar) -{ - return (-1); } APU_DECLARE(apr_status_t) apr_xlate_conv_buffer(apr_xlate_t *convset, Index: include/apr_xlate.h =================================================================== RCS file: /home/cvs/apr-util/include/apr_xlate.h,v retrieving revision 1.9 diff -u -r1.9 apr_xlate.h --- include/apr_xlate.h 13 Feb 2004 09:55:26 -0000 1.9 +++ include/apr_xlate.h 30 Mar 2004 13:08:00 -0000 @@ -127,17 +127,6 @@ #endif /** - * Convert a single-byte character from one charset to another. - * @param convset The handle allocated by apr_xlate_open, specifying the - * parameters of conversion - * @param inchar The single-byte character to convert. - * @warning This only works when converting between single-byte character sets. - * -1 will be returned if the conversion can't be performed. - */ -APU_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset, - unsigned char inchar); - -/** * Close a codepage translation handle. * @param convset The codepage translation handle to close * @remark