]> granicus.if.org Git - apache/commitdiff
Someone (I need to refer back) asked that we do the same skip for the
authorWilliam A. Rowe Jr <wrowe@apache.org>
Sun, 23 Feb 2003 22:37:35 +0000 (22:37 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Sun, 23 Feb 2003 22:37:35 +0000 (22:37 +0000)
  utf-8 win32 prefix when testing for shebang lines.  Here's just such
  a test with some bad sizeof(buffer) v.s. bytes read assumptions fixed,
  and the code made generally a little more legible.  Please review and
  comment to consider this patch for backporting to 2.0.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@98775 13f79535-47bb-0310-9956-ffa450edef68

modules/arch/win32/mod_win32.c

index 9104cf145f950a5168358c2ae9a332e72356d32f..937062046d63b8600b9ac66ba955c2c74e814a7b 100644 (file)
@@ -481,30 +481,52 @@ static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv,
         apr_status_t rv;
         char buffer[1024];
         apr_size_t bytes = sizeof(buffer);
-        int i;
+        apr_size_t i;
 
         /* Need to peek into the file figure out what it really is... 
          * ### aught to go back and build a cache for this one of these days.
          */
-        if (((rv = apr_file_open(&fh, *cmd, APR_READ | APR_BUFFERED,
-                                 APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) 
-            || ((rv = apr_file_read(fh, buffer, &bytes)) != APR_SUCCESS)) {
+        if ((rv = apr_file_open(&fh, *cmd, APR_READ | APR_BUFFERED,
+                                 APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) {
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                          "Failed to open cgi file %s for testing", *cmd);
+            return rv;
+        }
+        if ((rv = apr_file_read(fh, buffer, &bytes)) != APR_SUCCESS) {
             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                           "Failed to read cgi file %s for testing", *cmd);
             return rv;
         }
         apr_file_close(fh);
 
+        /* Some twisted character [no pun intended] at MS decided that a
+         * zero width joiner as the lead wide character would be ideal for
+         * describing Unicode text files.  This was further convoluted to
+         * another MSism that the same character mapped into utf-8, EF BB BF
+         * would signify utf-8 text files.
+         *
+         * Since MS configuration files are all protecting utf-8 encoded
+         * Unicode path, file and resource names, we already have the correct 
+         * WinNT encoding.  But at least eat the stupid three bytes up front.
+         *
+         * ### A more thorough check would also allow UNICODE text in buf, and
+         * convert it to UTF-8 for invoking unicode scripts.  Those are few
+         * and far between, so leave that code an enterprising soul with a need.
+         */
+        if ((bytes >= 3) && memcmp(buffer, "\xEF\xBB\xBF", 3) == 0) {
+            memmove(buffer, buffer + 3, bytes -= 3);
+        }
+
         /* Script or executable, that is the question... */
-        if ((buffer[0] == '#') && (buffer[1] == '!')) {
+        if ((bytes >= 2) && (buffer[0] == '#') && (buffer[1] == '!')) {
             /* Assuming file is a script since it starts with a shebang */
-            for (i = 2; i < sizeof(buffer); i++) {
+            for (i = 2; i < bytes; i++) {
                 if ((buffer[i] == '\r') || (buffer[i] == '\n')) {
                     buffer[i] = '\0';
                     break;
                 }
             }
-            if (i < sizeof(buffer)) {
+            if (i < bytes) {
                 interpreter = buffer + 2;
                 while (apr_isspace(*interpreter)) {
                     ++interpreter;
@@ -514,11 +536,10 @@ static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv,
                 }
             }
         }
-        else {
+        else if (bytes >= sizeof(IMAGE_DOS_HEADER)) {
             /* Not a script, is it an executable? */
             IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer;    
-            if ((bytes >= sizeof(IMAGE_DOS_HEADER))
-                && (hdr->e_magic == IMAGE_DOS_SIGNATURE)) {
+            if (hdr->e_magic == IMAGE_DOS_SIGNATURE) {
                 if (hdr->e_lfarlc < 0x40) {
                     /* Ought to invoke this 16 bit exe by a stub, (cmd /c?) */
                     interpreter = "";