Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 22272 invoked from network); 19 Oct 2005 08:40:00 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 19 Oct 2005 08:40:00 -0000 Received: (qmail 97724 invoked by uid 500); 19 Oct 2005 08:40:00 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 97691 invoked by uid 500); 19 Oct 2005 08:39:59 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 97677 invoked by uid 99); 19 Oct 2005 08:39:59 -0000 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Wed, 19 Oct 2005 01:39:58 -0700 Received: (qmail 22030 invoked by uid 65534); 19 Oct 2005 08:39:38 -0000 Message-ID: <20051019083938.22029.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r326478 - /incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classpath.c Date: Wed, 19 Oct 2005 08:39:38 -0000 To: harmony-commits@incubator.apache.org From: dlydick@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: dlydick Date: Wed Oct 19 01:39:22 2005 New Revision: 326478 URL: http://svn.apache.org/viewcvs?rev=326478&view=rev Log: Free heap blocks in error conditions in classpath_get_from_prchar() Substitute portable_XXX() version of system calls and library calls. Modify path names containing dollar sign '$' characters for inner class names for jar extraction script in classpath_get_from_prchar(). Added function classpath_inner_class_adjust() to do this. Updated ARCH_xxx() macros for better diagnostic support. Minor documentation adjustments. Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classpath.c Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classpath.c URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classpath.c?rev=326478&r1=326477&r2=326478&view=diff ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classpath.c (original) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/classpath.c Wed Oct 19 01:39:22 2005 @@ -15,7 +15,9 @@ * * @section Control * - * \$URL$ \$Id$ + * \$URL$ + * + * \$Id$ * * Copyright 2005 The Apache Software Foundation * or its licensors, as applicable. @@ -39,6 +41,7 @@ * @date \$LastChangedDate$ * * @author \$LastChangedBy$ + * * Original code contributed by Daniel Lydick on 09/28/2005. * * @section Reference @@ -46,12 +49,14 @@ */ #include "arch.h" -ARCH_COPYRIGHT_APACHE(classpath, c, "$URL$ $Id$"); +ARCH_SOURCE_COPYRIGHT_APACHE(classpath, c, +"$URL$", +"$Id$"); -#include -#include -#include +/* #include */ +/* #include */ +/* #include */ #include "jvmcfg.h" #include "cfmacros.h" @@ -88,13 +93,13 @@ * @returns @link #rvoid rvoid@endlink * * - * @todo Add proper searching for @c @b rt.jar file - * and @c @b Xbootclasspath . + * @todo HARMONY-6-jvm-classpath.c-1 Add proper searching + * for @c @b rt.jar file and @c @b Xbootclasspath . * For the moment, they are defined in * @link config.h config.h@endlink as the * @link #CONFIG_HACKED_RTJARFILE CONFIG_HACKED_RTJARFILE@endlink - * and - @link #CONFIG_HACKED_BOOTCLASSPATH CONFIG_HACKED_BOOTCLASSPATH@endlink + * and @link #CONFIG_HACKED_BOOTCLASSPATH + CONFIG_HACKED_BOOTCLASSPATH@endlink * pre-processor symbols and are commented in * @link jvm/src/jvmcfg.h jvmcfg.h@endlink after this * fashion. @@ -105,6 +110,8 @@ rvoid classpath_init() { + ARCH_FUNCTION_NAME(classpath_init); + /* Initialize only once */ if (rnull != classpath_list) { @@ -119,24 +126,26 @@ * @b CLASSPATH, followed by potential * CONFIG_HACKED_xxx definitions. */ - rchar *tmpclasspath; /* @b CLASSPATH dlm */ - rint tmpcplen = strlen(tmparea_get()) + sizeof(rchar) + - strlen(pjvm->classpath) + sizeof(rchar); + rchar *tmpclasspath; /* @b CLASSPATH dlm */ + rint tmpcplen = + portable_strlen(tmparea_get()) + sizeof(rchar) + + portable_strlen(pjvm->classpath) + sizeof(rchar); /* * Compensate for CONFIG_HACKED_xxx definitions, handy development * hooks for when @b CLASSPATH is in question. */ #ifdef CONFIG_HACKED_BOOTCLASSPATH - /* @b CLASSPATH dlm*/ - tmpcplen += strlen(CONFIG_HACKED_BOOTCLASSPATH) + sizeof(rchar); + /* @b CLASSPATH dlm */ + tmpcplen += + portable_strlen(CONFIG_HACKED_BOOTCLASSPATH) + sizeof(rchar); #endif #ifdef CONFIG_HACKED_RTJARFILE /* For $JAVA_HOME/$CONFIG_HACKED_RTJARFILE */ - tmpcplen += strlen(pjvm->java_home); + tmpcplen += portable_strlen(pjvm->java_home); tmpcplen += sizeof(rchar); - tmpcplen += strlen(CONFIG_HACKED_RTJARFILE) + sizeof(rchar); + tmpcplen += portable_strlen(CONFIG_HACKED_RTJARFILE) +sizeof(rchar); #endif tmpcplen += sizeof(rchar);/* NUL byte, possibly 1 more than needed*/ @@ -153,39 +162,39 @@ @link #CONFIG_HACKED_BOOTCLASSPATH CONFIG_HACKED_BOOTCLASSPATH@endlink: * @link #CONFIG_HACKED_RTJARFILE CONFIG_HACKED_RTJARFILE@endlink */ - strcpy(tmpclasspath, tmparea_get()); - i = strlen(tmpclasspath); + portable_strcpy(tmpclasspath, tmparea_get()); + i = portable_strlen(tmpclasspath); tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR; tmpclasspath[i + 1] = '\0'; - strcat(tmpclasspath, pjvm->classpath); + portable_strcat(tmpclasspath, pjvm->classpath); #ifdef CONFIG_HACKED_BOOTCLASSPATH - i = strlen(tmpclasspath); + i = portable_strlen(tmpclasspath); tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR; tmpclasspath[i + 1] = '\0'; - strcat(tmpclasspath, CONFIG_HACKED_BOOTCLASSPATH); + portable_strcat(tmpclasspath, CONFIG_HACKED_BOOTCLASSPATH); #endif #ifdef CONFIG_HACKED_RTJARFILE - i = strlen(tmpclasspath); + i = portable_strlen(tmpclasspath); tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR; tmpclasspath[i + 1] = '\0'; - strcat(tmpclasspath, pjvm->java_home); + portable_strcat(tmpclasspath, pjvm->java_home); - i = strlen(tmpclasspath); + i = portable_strlen(tmpclasspath); tmpclasspath[i] = CLASSPATH_ITEM_DELIMITER_CHAR; tmpclasspath[i + 1] = '\0'; - strcat(tmpclasspath, CONFIG_HACKED_RTJARFILE); + portable_strcat(tmpclasspath, CONFIG_HACKED_RTJARFILE); #endif HEAP_FREE_DATA(pjvm->classpath); /* May or may not be on heap */ pjvm->classpath = tmpclasspath; /* Keep for duration of pgm run */ - /* WARNING! NON-STANDARD TERMINATION CONDITION <= VERSUS < */ - for (i = 0, pathcount = 0; i <= strlen(tmpclasspath); i++) + /* @warning NON-STANDARD TERMINATION CONDITION <= VERSUS < */ + for (i = 0, pathcount = 0; i <= portable_strlen(tmpclasspath); i++) { if ((CLASSPATH_ITEM_DELIMITER_CHAR == tmpclasspath[i]) || - (i == strlen(tmpclasspath))) + (i == portable_strlen(tmpclasspath))) { pathcount++; } @@ -199,15 +208,15 @@ rint thislen; classpath_list_len = 0; - /* WARNING! NON-STANDARD TERMINATION CONDITION <= VERSUS < */ + /* @warning NON-STANDARD TERMINATION CONDITION <= VERSUS < */ for (i = 0, nextpath = tmpclasspath; - i <= strlen(tmpclasspath); + i <= portable_strlen(tmpclasspath); i++) { /* If found item delimiter OR END OF STRING (SEE ABOVE) */ if ((CLASSPATH_ITEM_DELIMITER_CHAR == tmpclasspath[i]) || - (i == strlen(tmpclasspath))) + (i == portable_strlen(tmpclasspath))) { /* calculate length of this @b CLASSPATH entry */ thislen = (&tmpclasspath[i]) - nextpath; @@ -236,9 +245,9 @@ HEAP_GET_DATA(thislen + sizeof(rchar), rfalse); /* Store current @b CLASSPATH item, including final '\0' */ - memcpy(classpath_list[classpath_list_len], - nextpath, - thislen); + portable_memcpy(classpath_list[classpath_list_len], + nextpath, + thislen); classpath_list[classpath_list_len][thislen] = '\0'; classpath_list_len++; @@ -268,18 +277,21 @@ * * @param pclasspath String from @b CLASSPATH list * + * * @returns @link #rtrue rtrue@endlink if string ends with * @c @b .jar, @link #rfalse rfalse@endlink otherwise. * */ rboolean classpath_isjar(rchar *pclasspath) { + ARCH_FUNCTION_NAME(classpath_isjar); + rint len, jarlen; - /* Lengths of test string and of JAR extension (w/ name.ext dlm)*/ - len = strlen(pclasspath); - jarlen = strlen(JVMCFG_EXTENSION_DELIMITER_STRING) + - strlen(CLASSFILE_EXTENSION_JAR); + /* Lengths of test string and of JAR extension (w/ name.ext dlm) */ + len = portable_strlen(pclasspath); + jarlen = portable_strlen(JVMCFG_EXTENSION_DELIMITER_STRING) + + portable_strlen(CLASSFILE_EXTENSION_JAR); /* For VERY short @b CLASSPATH entries, it cannot be a JAR file */ if (jarlen >= len) @@ -295,9 +307,9 @@ /* Now go test JAR extension since delimiter is present */ jarlen--; - if (0 == strncmp(&pclasspath[len - jarlen], - CLASSFILE_EXTENSION_JAR, - jarlen)) + if (0 == portable_strncmp(&pclasspath[len - jarlen], + CLASSFILE_EXTENSION_JAR, + jarlen)) { return(rtrue); } @@ -311,7 +323,7 @@ /*! * @brief Convert class name format external to internal form. - + * * The external format is @c @b class.name.format , while the * internal format is @c @b class/name/format . * Result is unchanged if it is already in internal format. @@ -325,21 +337,25 @@ * Call HEAP_FREE_DATA() when finished with buffer. * */ - rchar *classpath_external2internal_classname(rchar *clsname) { - rint len = strlen(clsname); + ARCH_FUNCTION_NAME(classpath_external2internal_classname); + + rint len = portable_strlen(clsname); rchar *rc = HEAP_GET_DATA(1 + len, rfalse); /* 1 + for NUL byte */ - memcpy(rc, clsname, 1 + len); /* 1 + for NUL byte */ + portable_memcpy(rc, clsname, 1 + len); /* 1 + for NUL byte */ return(classpath_external2internal_classname_inplace(rc)); } /* END of classpath_external2internal_classname() */ -/* - * In-place version of classpath_externam2internal_classname(): +/*! + * @brief Convert in place class name format external + * to internal form. + * + * In-place version of classpath_external2internal_classname(): * Takes an existing buffer and performs the conversion on it * @e without heap allocation. Return the input buffer. * @@ -353,8 +369,10 @@ */ rchar *classpath_external2internal_classname_inplace(rchar *inoutbfr) { + ARCH_FUNCTION_NAME(classpath_external2internal_classname_inplace); + rint i; - int len = strlen(inoutbfr); + int len = portable_strlen(inoutbfr); for (i = 0; i < len; i++) { @@ -374,6 +392,76 @@ /*! + * @brief Adjust class name string for shell expansion artifacts. + * + * Insert a backslash character in front of the dollar sign of any + * inner class name so that shell expansion does not see the dollar + * sign as a special character representing a shell variable. Unless + * this step is taken, such a shell variable, most likely non-existent, + * will effectively truncate the string before the dollar sign. + * + * + * @param pclass_location Null-terminated string containing a fully + * qualified class name, typically a path into a + * JAR file. + * + * + * @returns buffer address @b outbfr. When finished with this buffer, + * return it to the heap with + * @link #HEAP_FREE_DATA() HEAP_FREE_DATA@endlink. Notice + * that if a buffer has no dollar signs, this function + * is equivalent to strcpy(3). + * + */ +rchar *classpath_inner_class_adjust(rchar *pclass_location) +{ + ARCH_FUNCTION_NAME(classpath_inner_class_adjust); + + int len = portable_strlen(pclass_location); + + rint cllen = (rint) len; + rint i, j; + rint numdollar = 0; + +#ifndef CONFIG_WINDOWS + for (i = 0; i < cllen; i++) + { + if (CLASSNAME_INNERCLASS_MARKER_CHAR == pclass_location[i]) + { + numdollar++; + } + } +#endif + + rchar *outbfr = HEAP_GET_DATA(cllen + numdollar, rfalse); + + /* + * @warning NON-STANDARD TERMINATION CONDITION <= VERSUS < + * (so that NUL byte gets copied without any + * special consideration). + */ + for (i = 0, j = 0; i <= cllen; /* Done in body of loop: i++ */ ) + { + /* Windows platforms don't need these escapes */ +#ifndef CONFIG_WINDOWS + /* Insert escape character before dollar sign where found */ + if (CLASSNAME_INNERCLASS_MARKER_CHAR == pclass_location[i]) + { + outbfr[j++] = CLASSNAME_INNERCLASS_ESCAPE_CHAR; + } +#endif + + /* Copy next input character to output buffer */ + outbfr[j++] = pclass_location[i++]; + } + + /* Return buffer expanded with escapes where needed */ + return(outbfr); + +} /* END of classpath_inner_class_adjust() */ + + +/*! * @brief Search @b CLASSPATH for a given class name using a prchar. * * Return heap pointer to a buffer containing its location. @@ -406,16 +494,16 @@ * to distinguish between them. Thus the usage is, * Return @link #rnull rnull@endlink if no match. * - * @todo VM Spec section 5.3.1: Throw 'NoClassDeffoundError' - * if no match. + * @todo HARMONY-6-jvm-classpath.c-2 VM Spec section 5.3.1: Throw + * @b NoClassDeffoundError if no match. * - * Notice that @b clsname must be specified with package - * designations using INTERNAL (slash) delimiter form of - * the path. This is what is natively found in the class - * files. Of course, no package name means the simple - * default package, that is, an unpackaged class having - * no package some.package.name statement - * in source. + * Notice that @b clsname must be specified with package + * designations using INTERNAL (slash) delimiter form of + * the path. This is what is natively found in the class + * files. Of course, no package name means the simple + * default package, that is, an unpackaged class having + * no package some.package.name statement + * in source. * * @verbatim rchar *p = classpath_get_from_prchar( @@ -439,8 +527,11 @@ rchar *classpath_get_from_prchar(rchar *clsname) { + ARCH_FUNCTION_NAME(classpath_get_from_prchar); + + rvoid *statbfr; /* Portability library does (struct stat) part */ + rint i; - struct stat statbfr; rchar *name; int baselen; @@ -456,8 +547,8 @@ name = &clsname[1 + arraydims]; /* Calc position of end-of-class delimiter */ - rchar *pdlm = strchr(name, BASETYPE_CHAR_L_TERM); - baselen = strlen(name); + rchar *pdlm = portable_strchr(name, BASETYPE_CHAR_L_TERM); + baselen = portable_strlen(name); /* Should @e always be @link #rtrue rtrue@endlink */ if (rnull != pdlm) @@ -474,7 +565,7 @@ * array dimensions. */ name = clsname; - baselen = strlen(name); + baselen = portable_strlen(name); } rchar *jarscript = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse); @@ -492,21 +583,23 @@ if (rtrue == classpath_isjar(classpath_list[i])) { /* Convert input parm to internal form, append suffix */ - strcpy(class_location, name); - clen = strlen(class_location); + portable_strcpy(class_location, name); + clen = portable_strlen(class_location); (rvoid) classpath_external2internal_classname_inplace( class_location); class_location[clen] = JVMCFG_EXTENSION_DELIMITER_CHAR; class_location[clen + 1] = '\0'; - strcat(class_location, CLASSFILE_EXTENSION_DEFAULT); + portable_strcat(class_location, + CLASSFILE_EXTENSION_DEFAULT); + + rchar *inner_class_location = + classpath_inner_class_adjust(class_location); /*! * @internal Build up JAR command using internal class name - * with suffix. Make @e sure all files are writeable - * for final rm -rf. + * with suffix. Make @e sure all files are + * writeable for final rm -rf. */ - - sprintfLocal(jarscript, JVMCFG_JARFILE_DATA_EXTRACT_SCRIPT, tmparea_get(), @@ -514,47 +607,75 @@ pjvm->java_home, JVMCFG_PATHNAME_DELIMITER_CHAR, classpath_list[i], - class_location); + inner_class_location); + +#if defined(CONFIG_WINDOWS) || defined(CONFIG_CYGWIN) + + /* + * @todo HARMONY-6-jvm-classpath.c-3 + * gmj : awful hack - need to escape out every \ in paths + * or it doesn't seem to get across into the batch file + * correctly + */ + rchar *fixscript = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse); + + char *buffptr = fixscript; + char *jarscriptPtr = jarscript; + + char c; + while((c = *jarscriptPtr++)) + { + *buffptr++ = c; + +#if defined(CONFIG_WINDOWS) + if (c == JVMCFG_PATHNAME_DELIMITER_CHAR) + { + *buffptr++ = JVMCFG_PATHNAME_DELIMITER_CHAR; + } +#endif +#if defined(CONFIG_CYGWIN) + /* + * CygWin can have both-- + * such as C:\\path\\name/more/path/name + */ + if (c == JVMCFG_PATHNAME_ALT_DELIMITER_CHAR) + { + *buffptr++ = JVMCFG_PATHNAME_ALT_DELIMITER_CHAR; + } +#endif + } + *buffptr = '\0'; -#ifdef CONFIG_WINDOWS + portable_strcpy(jarscript, fixscript); + HEAP_FREE_DATA(fixscript); - /* - * gmj : awful hack - need to escape out every \ in paths - * or it doesn't seem to get across into the batch file correctly - */ - rchar *fixscript = HEAP_GET_DATA(JVMCFG_SCRIPT_MAX, rfalse); - - char *buffptr = fixscript; - char *jarscriptPtr = jarscript; - - char c; - while((c = *jarscriptPtr++)) { - *buffptr++ = c; - - if (c == '\\') - { - *buffptr++ = '\\'; - } - } - *buffptr = '\0'; - - strcpy(jarscript, fixscript); - HEAP_FREE_DATA(fixscript); - #endif - int rc = system(jarscript); + HEAP_FREE_DATA(inner_class_location); + + int rc = portable_system(jarscript); if (0 != rc) { - sysErrMsg("classpath_get_from_prchar", + sysErrMsg(arch_function_name, "Cannot extract '%s' from JAR file %s", - class_location, + inner_class_location, classpath_list[i]); + + HEAP_FREE_DATA(class_location); + HEAP_FREE_DATA(jarscript); + exit_jvm(EXIT_CLASSPATH_JAR); /*NOTREACHED*/ } + /* + * @todo HARMONY-6-jvm-classpath.c-4 Make sure that this + * sprintf/stat works with both CONFIG_WINDOWS and + * CONFIG_CYGWIN. + * + */ + /* Location of extracted file */ sprintfLocal(jarscript, "%s%c%s", @@ -562,13 +683,14 @@ JVMCFG_PATHNAME_DELIMITER_CHAR, class_location); - rc = stat(jarscript, &statbfr); + statbfr = portable_stat(jarscript); + HEAP_FREE_DATA(statbfr); /* * If file was extracted, report result * in heap-allocated bfr */ - if (0 == rc) + if (rnull != statbfr) { HEAP_FREE_DATA(class_location); @@ -579,15 +701,22 @@ } else { + /* + * @todo HARMONY-6-jvm-classpath.c-4 Make sure that this + * sprintf/stat works with both CONFIG_WINDOWS and + * CONFIG_CYGWIN. + * + */ + /* Convert input parm to internal form */ sprintfLocal(class_location, "%s%c\0", classpath_list[i], JVMCFG_PATHNAME_DELIMITER_CHAR); - clen = strlen(class_location); + clen = portable_strlen(class_location); - strcat(class_location, name); + portable_strcat(class_location, name); /* * Convert input parm to internal format and append @@ -604,15 +733,19 @@ JVMCFG_EXTENSION_DELIMITER_CHAR; class_location[clen + baselen + 1] = '\0'; - strcat(class_location, CLASSFILE_EXTENSION_DEFAULT); + portable_strcat(class_location, + CLASSFILE_EXTENSION_DEFAULT); } /* Test for existence of valid class file */ - int rc = stat(class_location, &statbfr); + statbfr = portable_stat(class_location); + HEAP_FREE_DATA(statbfr); /* If match found, report result in heap-allocated bfr */ - if (0 == rc) + if (rnull != statbfr) { + HEAP_FREE_DATA(jarscript); + return(class_location); } } @@ -620,6 +753,8 @@ /* Class not found in @b CLASSPATH */ HEAP_FREE_DATA(class_location); + HEAP_FREE_DATA(jarscript); + return((rchar *) rnull); } /* END of classpath_get_from_prchar() */ @@ -652,6 +787,8 @@ rchar *classpath_get_from_cp_entry_utf(cp_info_dup *clsname) { + ARCH_FUNCTION_NAME(classpath_get_from_cp_entry_utf); + rchar *prchar_clsname = utf_utf2prchar(PTR_THIS_CP_Utf8(clsname)); rchar *rc = classpath_get_from_prchar(prchar_clsname); @@ -670,11 +807,13 @@ * @b Parameters: @link #rvoid rvoid@endlink * * - * @returns @link #rvoid rvoid@endlink + * @returns @link #rvoid rvoid@endlink * */ rvoid classpath_shutdown() { + ARCH_FUNCTION_NAME(classpath_shutdown); + rint i; for (i = 0; i < classpath_list_len; i++)