summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c')
-rw-r--r--gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c322
1 files changed, 262 insertions, 60 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
index 210eedcf641..2177a108910 100644
--- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
+++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
@@ -272,11 +272,12 @@ PUBLIC char * HTSACopy ARGS2(
{
if (src != 0) {
if (src != *dest) {
+ size_t size = strlen(src) + 1;
FREE(*dest);
- *dest = (char *) malloc (strlen(src) + 1);
+ *dest = (char *) malloc(size);
if (*dest == NULL)
outofmem(__FILE__, "HTSACopy");
- strcpy (*dest, src);
+ memcpy(*dest, src, size);
}
} else {
FREE(*dest);
@@ -292,7 +293,7 @@ PUBLIC char * HTSACat ARGS2(
{
if (src && *src && (src != *dest)) {
if (*dest) {
- int length = strlen(*dest);
+ size_t length = strlen(*dest);
*dest = (char *)realloc(*dest, length + strlen(src) + 1);
if (*dest == NULL)
outofmem(__FILE__, "HTSACat");
@@ -308,6 +309,45 @@ PUBLIC char * HTSACat ARGS2(
}
+/* optimized for heavily realloc'd strings, store length inside */
+
+#define EXTRA_TYPE size_t /* type we use for length */
+#define EXTRA_SIZE sizeof(void *) /* alignment >= sizeof(EXTRA_TYPE) */
+
+PUBLIC void HTSAFree_extra ARGS1(
+ char *, s)
+{
+ free(s - EXTRA_SIZE);
+}
+
+/* never shrink */
+PUBLIC char * HTSACopy_extra ARGS2(
+ char **, dest,
+ CONST char *, src)
+{
+ if (src != 0) {
+ size_t srcsize = strlen(src) + 1;
+ EXTRA_TYPE size = 0;
+
+ if (*dest != 0) {
+ size = *(EXTRA_TYPE *)((*dest) - EXTRA_SIZE);
+ }
+ if (size < srcsize) {
+ FREE_extra(*dest);
+ size = srcsize * 2; /* x2 step */
+ *dest = (char *) malloc(size + EXTRA_SIZE);
+ if (*dest == NULL)
+ outofmem(__FILE__, "HTSACopy_extra");
+ *(EXTRA_TYPE *)(*dest) = size;
+ *dest += EXTRA_SIZE;
+ }
+ memcpy(*dest, src, srcsize);
+ } else {
+ Clear_extra(*dest);
+ }
+ return *dest;
+}
+
/* Find next Field
** ---------------
**
@@ -389,7 +429,8 @@ PUBLIC char * HTNextTok ARGS4(
BOOL get_comments;
BOOL get_closing_char_too = FALSE;
char closer;
- if (!pstr || !*pstr) return NULL;
+
+ if (isEmpty(pstr)) return NULL;
if (!delims) delims = " ;,=" ;
if (!bracks) bracks = "<\"" ;
@@ -502,9 +543,9 @@ PRIVATE char *HTAlloc ARGS2(char *, ptr, size_t, length)
#endif
/*
- * Replacement for sprintf, allocates buffer on the fly according to what's needed
- * for its arguments. Unlike sprintf, this always concatenates to the destination
- * buffer, so we do not have to provide both flavors.
+ * Replacement for sprintf, allocates buffer on the fly according to what's
+ * needed for its arguments. Unlike sprintf, this always concatenates to the
+ * destination buffer, so we do not have to provide both flavors.
*/
typedef enum { Flags, Width, Prec, Type, Format } PRINTF;
@@ -748,9 +789,9 @@ PUBLIC_IF_FIND_LEAKS char * StrAllocVsprintf ARGS4(
#undef SAVE_TIME_NOT_SPACE
/*
- * Replacement for sprintf, allocates buffer on the fly according to what's needed
- * for its arguments. Unlike sprintf, this always concatenates to the destination
- * buffer.
+ * Replacement for sprintf, allocates buffer on the fly according to what's
+ * needed for its arguments. Unlike sprintf, this always concatenates to the
+ * destination buffer.
*/
/* Note: if making changes, also check the memory tracking version
* LYLeakHTSprintf in LYLeaks.c. - kw */
@@ -960,34 +1001,30 @@ PUBLIC void HTAddXpand ARGS4(
#endif /* USE_QUOTED_PARAMETER */
/*
- * Append string-parameter to a system command that we are constructing. The
- * string is a complete parameter (which is a necessary assumption so we can
- * quote it properly). We're given the index of the newest parameter we're
- * processing. Zero indicates none, so a value of '1' indicates that we copy
- * from the beginning of the command string up to the first parameter,
- * substitute the quoted parameter and return the result.
+ * Append string to a system command that we are constructing, without quoting.
+ * We're given the index of the newest parameter we're processing. Zero
+ * indicates none, so a value of '1' indicates that we copy from the beginning
+ * of the command string up to the first parameter, substitute the quoted
+ * parameter and return the result.
*
* Parameters are substituted at "%s" tokens, like printf. Other printf-style
* tokens are not substituted; they are passed through without change.
*/
-PUBLIC void HTAddParam ARGS4(
+PUBLIC void HTAddToCmd ARGS4(
char **, result,
CONST char *, command,
int, number,
- CONST char *, parameter)
+ CONST char *, string)
{
if (number > 0) {
CONST char *last = HTAfterCommandArg(command, number - 1);
CONST char *next = last;
-#if USE_QUOTED_PARAMETER
- char *quoted;
-#endif
if (number <= 1) {
FREE(*result);
}
- if (parameter == 0)
- parameter = "";
+ if (string == 0)
+ string = "";
while (next[0] != 0) {
if (HTIsParam(next)) {
if (next != last) {
@@ -996,13 +1033,7 @@ PUBLIC void HTAddParam ARGS4(
HTSACat(result, last);
(*result)[len] = 0;
}
-#if USE_QUOTED_PARAMETER
- quoted = HTQuoteParameter(parameter);
- HTSACat(result, quoted);
- FREE(quoted);
-#else
- HTSACat(result, parameter);
-#endif
+ HTSACat(result, string);
CTRACE((tfp, "PARAM-ADD:%s\n", *result));
return;
}
@@ -1012,6 +1043,28 @@ PUBLIC void HTAddParam ARGS4(
}
/*
+ * Append string-parameter to a system command that we are constructing. The
+ * string is a complete parameter (which is a necessary assumption so we can
+ * quote it properly).
+ */
+PUBLIC void HTAddParam ARGS4(
+ char **, result,
+ CONST char *, command,
+ int, number,
+ CONST char *, parameter)
+{
+ if (number > 0) {
+#if USE_QUOTED_PARAMETER
+ char *quoted = HTQuoteParameter(parameter);
+ HTAddToCmd(result, command, number, quoted);
+ FREE(quoted);
+#else
+ HTAddToCmd(result, command, number, parameter);
+#endif
+ }
+}
+
+/*
* Append the remaining command-string to a system command (compare with
* HTAddParam). Any remaining "%s" tokens are copied as empty strings.
*/
@@ -1022,6 +1075,7 @@ PUBLIC void HTEndParam ARGS3(
{
CONST char *last;
int count;
+
count = HTCountCommandArgs (command);
if (count < number)
number = count;
@@ -1033,11 +1087,11 @@ PUBLIC void HTEndParam ARGS3(
}
-#ifdef EXP_FILE_UPLOAD
-/* bstring Allocate and Concatenate
-*/
+/* Binary-strings (may have embedded nulls).
+ * Some modules (HTGopher) assume there is a null on the end, anyway.
+ */
-/* Allocate a new copy of a bstring, and returns it
+/* Allocate a new bstring, and return it.
*/
PUBLIC void HTSABCopy ARGS3(
bstring**, dest,
@@ -1045,51 +1099,199 @@ PUBLIC void HTSABCopy ARGS3(
int, len)
{
bstring *t;
- CTRACE((tfp, "HTSABCopy(%p, %p, %d)\n", dest, src, len));
- /* if we already have a bstring ** ... */
- if (dest) {
- /* ... with a valid bstring *, free it ... */
- if (*dest) {
- FREE((*dest)->str);
- FREE(*dest);
- }
- *dest = malloc(sizeof(bstring));
- if (src) {
- CTRACE((tfp, "%% [%s]\n", src));
- t = (bstring*) malloc(sizeof(bstring));
- if (t == NULL)
- outofmem(__FILE__, "HTSABCopy");
- t->str = (char *) malloc (len);
- if (t->str == NULL)
- outofmem(__FILE__, "HTSABCopy");
- memcpy (t->str, src, len);
- t->len = len;
- *dest = t;
+ unsigned need = len + 1;
+
+ CTRACE2(TRACE_BSTRING, (tfp, "HTSABCopy(%p, %p, %d)\n", dest, src, len));
+ HTSABFree(dest);
+ if (src) {
+ if (TRACE_BSTRING) {
+ CTRACE((tfp, "=== %4d:", len));
+ trace_bstring2(src, len);
+ CTRACE((tfp, "\n"));
}
+ if ((t = (bstring*) malloc(sizeof(bstring))) == NULL)
+ outofmem(__FILE__, "HTSABCopy");
+ if ((t->str = (char *) malloc (need)) == NULL)
+ outofmem(__FILE__, "HTSABCopy");
+ memcpy (t->str, src, len);
+ t->len = len;
+ t->str[t->len] = '\0';
+ *dest = t;
+ }
+ if (TRACE_BSTRING) {
+ CTRACE((tfp, "=> %4d:", BStrLen(*dest)));
+ trace_bstring(*dest);
+ CTRACE((tfp, "\n"));
}
}
+/*
+ * Initialize with a null-terminated string (discards the null).
+ */
+PUBLIC void HTSABCopy0 ARGS2(
+ bstring**, dest,
+ CONST char *, src)
+{
+ HTSABCopy(dest, src, strlen(src));
+}
+
+/*
+ * Append a block of memory to a bstring.
+ */
PUBLIC void HTSABCat ARGS3(
bstring **, dest,
CONST char *, src,
int, len)
{
bstring *t = *dest;
+
+ CTRACE2(TRACE_BSTRING, (tfp, "HTSABCat(%p, %p, %d)\n", dest, src, len));
if (src) {
+ unsigned need = len + 1;
+
+ if (TRACE_BSTRING) {
+ CTRACE((tfp, "=== %4d:", len));
+ trace_bstring2(src, len);
+ CTRACE((tfp, "\n"));
+ }
if (t) {
- int length = t->len;
- t->str = (char *)realloc(t->str, length + len);
+ unsigned length = t->len + need;
+ if ((t->str = (char *)realloc(t->str, length)) == NULL)
+ outofmem(__FILE__, "HTSACat");
} else {
- t = typecalloc(bstring);
- if (t == NULL)
+ if ((t = typecalloc(bstring)) == NULL)
outofmem(__FILE__, "HTSACat");
- t->str = (char *)malloc(len);
+ t->str = (char *)malloc(need);
}
if (t->str == NULL)
outofmem(__FILE__, "HTSACat");
memcpy (t->str + t->len, src, len);
t->len += len;
+ t->str[t->len] = '\0';
*dest = t;
}
+ if (TRACE_BSTRING) {
+ CTRACE((tfp, "=> %4d:", BStrLen(*dest)));
+ trace_bstring(*dest);
+ CTRACE((tfp, "\n"));
+ }
+}
+
+/*
+ * Append a null-terminated string (discards the null).
+ */
+PUBLIC void HTSABCat0 ARGS2(
+ bstring**, dest,
+ CONST char *, src)
+{
+ HTSABCat(dest, src, strlen(src));
+}
+
+/*
+ * Compare two bstring's for equality
+ */
+PUBLIC BOOL HTSABEql ARGS2(
+ bstring *, a,
+ bstring *, b)
+{
+ unsigned len_a = (a != 0) ? a->len : 0;
+ unsigned len_b = (b != 0) ? b->len : 0;
+
+ if (len_a == len_b) {
+ if (len_a == 0
+ || memcmp(a->str, b->str, a->len) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * Deallocate a bstring.
+ */
+PUBLIC void HTSABFree ARGS1(
+ bstring **, ptr)
+{
+ if (*ptr != NULL) {
+ FREE((*ptr)->str);
+ FREE(*ptr);
+ *ptr = NULL;
+ }
+}
+
+/*
+ * Use this function to perform formatted sprintf's onto the end of a bstring.
+ * The bstring may contain embedded nulls; the formatted portions must not.
+ */
+#ifdef ANSI_VARARGS
+PUBLIC bstring * HTBprintf (bstring ** pstr, CONST char * fmt, ...)
+#else
+PUBLIC bstring * HTBprintf (va_alist)
+ va_dcl
+#endif
+{
+ bstring *result = 0;
+ char *temp = 0;
+ va_list ap;
+
+ LYva_start(ap,fmt);
+ {
+#if !ANSI_VARARGS
+ bstring ** pstr = va_arg(ap, char **);
+ CONST char * fmt = va_arg(ap, CONST char *);
+#endif
+ temp = StrAllocVsprintf(&temp, 0, fmt, &ap);
+ if (!isEmpty(temp)) {
+ HTSABCat (pstr, temp, strlen(temp));
+ }
+ FREE(temp);
+ result = *pstr;
+ }
+ va_end(ap);
+
+ return (result);
+}
+
+/*
+ * Write binary-data to the logfile, making it safe for most editors to view.
+ * That is most, since we do not restrict line-length. Nulls and other
+ * non-printing characters are addressed.
+ */
+PUBLIC void trace_bstring2 ARGS2(
+ CONST char *, text,
+ int, size)
+{
+ int n;
+
+ if (text != 0) {
+ for (n = 0; n < size; ++n) {
+ int ch = UCH(text[n]);
+ switch (ch) {
+ case '\\':
+ fputs("\\\\", tfp);
+ break;
+ case '\r':
+ fputs("\\r", tfp);
+ break;
+ case '\t':
+ fputs("\\t", tfp);
+ break;
+ case '\f':
+ fputs("\\f", tfp);
+ break;
+ default:
+ if (isprint(ch) || isspace(ch)) {
+ fputc(ch, tfp);
+ } else {
+ fprintf(tfp, "\\%03o", ch);
+ }
+ break;
+ }
+ }
+ }
+}
+
+PUBLIC void trace_bstring ARGS1(
+ bstring *, data)
+{
+ trace_bstring2(BStrData(data), BStrLen(data));
}
-#endif /* EXP_FILE_UPLOAD */