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

Reply via email to