Beispiel #1
0
/*
 * This routine is a replacement for the old, horrible strcat() loop
 * that was used to turn the argv[] array into a string for CreateProcess().
 * It's about a zillion times faster. 
 * -amol 2/4/99
 */
char *concat_args_and_quote(char **args, char **poriginalPtr,char **cstr, 
  unsigned int *clen, char **cend, unsigned int *cmdsize) {

	unsigned int argcount, arglen, cmdlen;
	char *tempptr, *cmdend ,*cmdstr;
	short quotespace = 0;
	short quotequote = 0;
	short noquoteprotect = 0;
	char *tempquotedbuf;
	unsigned long tqlen = 256;
	int rc;

	dprintf("entering concat_args_and_quote\n");
	tempquotedbuf = heap_alloc(tqlen);

	noquoteprotect = (varval(STRNTnoquoteprotect) != STRNULL);
	/* 
		quotespace hack needed since execv() would have separated args, but
		createproces doesnt
		-amol 9/14/96
	*/
	cmdend= *cend;
	cmdstr = *cstr;
	cmdlen = *clen;

	argcount = 0;
	while (*args) {

		*cmdend++ = ' ';
		cmdlen++;

		tempptr = *args;

		arglen = 0;
		argcount++;

		//dprintf("args is %s\n",*args);
		if (!*tempptr) {
			*cmdend++ = '"';
			*cmdend++ = '"';
		}
		while(*tempptr) {
			if (*tempptr == ' ' || *tempptr == '\t') 
				quotespace = 1;
			else if (*tempptr == '"')
				quotequote = 1;
			tempptr++;
			arglen++;
		}
        if (arglen + cmdlen +4 > *cmdsize) { // +4 is if we have to quote

			dprintf("before realloc: original %p, cmdstr %p\n",
				*poriginalPtr,cmdstr);

            tempptr = heap_realloc(*poriginalPtr,*cmdsize<<1);

			if(!tempptr)
				return NULL;

			// If it's not the same heap block, re-adjust the pointers.
            if (tempptr != *poriginalPtr) {
				cmdstr = tempptr + (cmdstr - *poriginalPtr);
                cmdend = tempptr + (cmdend- *poriginalPtr);
				*poriginalPtr = tempptr;
            }
			dprintf("after realloc: original %p, cmdstr %p\n",
				*poriginalPtr,cmdstr);

            *cmdsize <<=1;
        }
		if (quotespace)
			*cmdend++ = '"';

        if ((noquoteprotect == 0) && quotequote){
            tempquotedbuf[0]=0;

            tempptr = &tempquotedbuf[0];

            rc = quoteProtect(tempquotedbuf,*args,tqlen);

			while(rc == ERROR_BUFFER_OVERFLOW) {
				tempquotedbuf = heap_realloc(tempquotedbuf,tqlen <<1);
				tqlen <<= 1;
				tempptr = &tempquotedbuf[0];
				rc = quoteProtect(tempquotedbuf,*args,tqlen);
			}
            while (*tempptr) {
                *cmdend = *tempptr;
                cmdend++;
                tempptr++;
            }
            cmdlen +=2;
        }
        else {
            tempptr = *args;
            while(*tempptr) {
                *cmdend = *tempptr;
                cmdend++;
                tempptr++;
            }
        }

        if (quotespace) {
            *cmdend++ = '"';
            cmdlen +=2;
        }
        cmdlen += arglen;

        args++;
	}
	*clen = cmdlen;
	*cend = cmdend;
	*cstr = cmdstr;

	heap_free(tempquotedbuf);


	return cmdstr;
}
Beispiel #2
0
/*
 * args is the const array to be quoted and concatenated
 * *cstr is the resulting string
 * *clen is current cstr size
 * *cend points to the end of the constructed string
 * *cmdsize is the cstr buffer size
 *
 * PROBLEMS:
 *      - heap_realloc() is not tested for failure
 *      - when re-allocating the passed-in *cstr pointer is lost, generating a leak
 *
 * This routine is a replacement for the old, horrible strcat() loop
 * that was used to turn the argv[] array into a string for CreateProcess().
 * It's about a zillion times faster.
 * -amol 2/4/99
 */
static void concat_args_and_quote(const char *const *args, char **cstr, size_t *clen,
                                  char **cend, unsigned int *cmdsize) {

	unsigned int argcount, arglen;
	size_t cmdlen;
	const char *tempptr;
	char *cmdend, *cmdstr;
	short quotespace;
	short quotequote;
	short n_quotequote;

	/*
		quotespace hack needed since execv() would have separated args, but
		createproces doesnt
		-amol 9/14/96
	*/
	cmdend= *cend;
	cmdstr = *cstr;
	cmdlen = *clen;

	argcount = 0;
	while (*args && (cmdlen < 65500) ) {

		argcount++;
		arglen = 0;

		/* first, count the current argument and check if we need to quote. */
		quotespace = quotequote = n_quotequote = 0;
		tempptr = *args;

		if(!*tempptr) {
			/* check for empty argument, will be replaced by "" */
			quotespace = 1;
		}
		else {
			/* count spaces, tabs and quotes. */
			while(*tempptr) {
				if (*tempptr == ' ' || *tempptr == '\t')
					quotespace = 1;
				else if (*tempptr == '"') {
					quotequote = 1;
					n_quotequote++;
				} else if (*tempptr == '\\') {
					n_quotequote++;
				}
				tempptr++;
				arglen++;
			}
		}

		/* Next, realloc target string if necessary */
		while (cmdlen + 2 + arglen + 2*quotespace + quotequote * n_quotequote > *cmdsize) {
			tempptr = cmdstr;
			dbgprintf(PR_WARN, "Heap realloc before %p\n", cmdstr);
			cmdstr = (char *)heap_realloc(cmdstr, *cmdsize<<1);
			/* @@@@ does NOT test for failure ... */
			if (tempptr != cmdstr) {
				cmdend = cmdstr + (cmdend-tempptr);
			}
			dbgprintf(PR_WARN, "Heap realloc after %p\n", cmdstr);
			*cmdsize <<=1;
		}

		/* add space before next argument */
		*cmdend++ = ' ';
		cmdlen++;

		if (quotespace) {
			/* we need to quote, so output a quote. */
			*cmdend++ = '"';
			cmdlen++;
		}

		if (n_quotequote > 0){
			/* quote quotes and copy into the destination */
			*cmdend=0;
			quoteProtect(cmdend,*args);
			while(*cmdend) {
				cmdend++;
				cmdlen++;
			}
		} else {
			/* directly copy the argument into the destination */
			tempptr = *args;
			while(*tempptr) {
				*cmdend++ = *tempptr++;
				cmdlen++;
			}
		}

		if (quotespace) {
			*cmdend++ = '"';
			cmdlen ++;
		}

		args++;
	}
	*clen = cmdlen;
	*cend = cmdend;
	*cstr = cmdstr;

}