php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #1755 base64_decode uses inefficient algorithm
Submitted: 1999-07-20 12:34 UTC Modified: 1999-07-21 05:03 UTC
From: bfranklin at dct dot com Assigned:
Status: Closed Package: Performance problem
PHP Version: 4.0 Beta 1 OS: Sparc Solaris 2.7
Private report: No CVE-ID: None
 [1999-07-20 12:34 UTC] bfranklin at dct dot com
Base64_decode uses strchr to lookup the location of a character in base64_table[], causing a function call and (on average) 32 comparisons per encoded character.

It would be far more efficient to build a static array of reverse lookup values to use.

Here's a patch to fix this:
--- base64.c.orig       Tue Jul 20 10:29:42 1999
+++ base64.c    Tue Jul 20 10:51:54 1999
@@ -71,18 +71,34 @@
 unsigned char *_php3_base64_decode(const unsigned char *string, int length, int *ret_length) {
        const unsigned char *current = string;
        int ch, i = 0, j = 0, k;
+       static int reverse_table[256];
+       static int table_built = 0;
 
        unsigned char *result = (unsigned char *)emalloc((length / 4 * 3 + 1) * sizeof(char));
        if (result == NULL) {
                return NULL;
        }
 
+       /* build table of reverse mappings to speed things up */
+       if( ! table_built )
+       {
+               char *chp;
+               for(ch=0;ch<256;ch++)
+               {
+                       chp = strchr(base64_table, ch);
+                       if( chp != NULL )
+                               reverse_table[ch] = chp - base64_table;
+                       else
+                               reverse_table[ch] = -1;
+               }
+               table_built = 1;
+       }
+
        /* run through the whole string, converting as we go */
        while ((ch = *current++) != '\0') {
                if (ch == base64_pad) break;
-               ch = (int)strchr(base64_table, ch);
-               if (ch == 0) continue;
-               ch -= (int)base64_table;
+               ch = reverse_table[ch];
+               if (ch < 0) continue;
 
                switch(i % 4) {
                case 0:

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [1999-07-21 05:03 UTC] sas at cvs dot php dot net
Thanks, patch applieds
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 20:01:28 2024 UTC