]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
cachemgr.cgi: use dynamic MemBuf for internal content generation
authorAmos Jeffries <squid3@treenet.co.nz>
Wed, 20 Apr 2016 10:11:48 +0000 (22:11 +1200)
committerAmos Jeffries <squid3@treenet.co.nz>
Wed, 20 Apr 2016 10:11:48 +0000 (22:11 +1200)
Using a fixed size buffer limits how big content lines can be. Modern
HTTP is fast reaching the point where such limits are problematic.
Also fixes incorrect uses of snprintf() by removing them.

src/tests/Stub.list
src/tests/stub_cbdata.cc [new file with mode: 0644]
src/tests/stub_mem.cc
tools/Makefile.am
tools/cachemgr.cc

index 6348ff8ddef499b0ffb9f56a6c8eb84551d02f0c..abe5132a6604370bfe1c12d964fc6d4b19930520 100644 (file)
@@ -14,6 +14,7 @@ STUB_SOURCE= tests/STUB.h \
        tests/stub_acl.cc \
        tests/stub_cache_cf.cc \
        tests/stub_cache_manager.cc \
+       tests/stub_cbdata.cc \
        tests/stub_client_db.cc \
        tests/stub_client_side_request.cc \
        tests/stub_comm.cc \
diff --git a/src/tests/stub_cbdata.cc b/src/tests/stub_cbdata.cc
new file mode 100644 (file)
index 0000000..d91b309
--- /dev/null
@@ -0,0 +1,30 @@
+#include "squid.h"
+#include "cbdata.h"
+
+#define STUB_API "cbdata.cc"
+#include "tests/STUB.h"
+
+void cbdataRegisterWithCacheManager(void) STUB
+void *cbdataInternalAlloc(cbdata_type type, const char *, int sz) {
+    return xcalloc(1, sz);
+}
+void *cbdataInternalFree(void *p, const char *, int) {
+    xfree(p);
+    return NULL;
+}
+#if USE_CBDATA_DEBUG
+void *cbdataInternalAllocDbg(cbdata_type type, const char *, int) STUB_RETVAL(NULL)
+void *cbdataInternalFreeDbg(void *p, const char *, int) STUB_RETVAL(NULL)
+void cbdataInternalLockDbg(const void *p, const char *, int) STUB
+void cbdataInternalUnlockDbg(const void *p, const char *, int) STUB
+int cbdataInternalReferenceDoneValidDbg(void **p, void **tp, const char *, int) STUB_RETVAL(0)
+#else
+void *cbdataInternalAlloc(cbdata_type type) STUB_RETVAL(NULL)
+void *cbdataInternalFree(void *p) STUB_RETVAL(NULL)
+void cbdataInternalLock(const void *p) STUB
+void cbdataInternalUnlock(const void *p) STUB
+int cbdataInternalReferenceDoneValid(void **p, void **tp) STUB_RETVAL(0)
+#endif
+
+int cbdataReferenceValid(const void *p) STUB_RETVAL(0)
+cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size, FREE * free_func) STUB_RETVAL(CBDATA_UNKNOWN)
index 53cc877b1fb69e55f92700860770b8e9593b72e3..5d5050afd31e498d4c60cf485cb44c31783a06d2 100644 (file)
@@ -5,7 +5,7 @@
 #include "squid.h"
 
 #define STUB_API "stub_mem.cc"
-#include "STUB.h"
+#include "tests/STUB.h"
 /* mem* definitions are still in protos.h */
 #include "protos.h"
 
index a22e37b397df3fed863ad535ada1e6c37b8e07f3..aa8d78997ac05d4c36a5f8f9213340b45d8f8409 100644 (file)
@@ -34,15 +34,24 @@ test_tools.cc: $(top_srcdir)/test-suite/test_tools.cc
 stub_debug.cc: $(top_srcdir)/src/tests/stub_debug.cc
        cp $(top_srcdir)/src/tests/stub_debug.cc .
 
+MemBuf.cc: $(top_srcdir)/src/MemBuf.cc
+       cp $(top_srcdir)/src/MemBuf.cc $@
+
 time.cc: $(top_srcdir)/src/time.cc
        cp $(top_srcdir)/src/time.cc .
 
+stub_cbdata.cc: $(top_srcdir)/src/tests/stub_cbdata.cc
+       cp $(top_srcdir)/src/tests/stub_cbdata.cc $@
+
+stub_mem.cc: $(top_srcdir)/src/tests/stub_mem.cc
+       cp $(top_srcdir)/src/tests/stub_mem.cc $@
+
 # stock tools for unit tests - library independent versions of dlink_list
 # etc.
 # globals.cc is needed by test_tools.cc.
 # Neither of these should be disted from here.
 TESTSOURCES= test_tools.cc
-CLEANFILES += test_tools.cc stub_debug.cc time.cc
+CLEANFILES += test_tools.cc MemBuf.cc stub_debug.cc time.cc stub_cbdata.cc stub_mem.cc
 
 ## ##### helper-mux #####
 
@@ -73,7 +82,10 @@ DEFAULT_CACHEMGR_CONFIG = $(sysconfdir)/cachemgr.conf
 libexec_PROGRAMS = cachemgr$(CGIEXT)
 
 cachemgr__CGIEXT__SOURCES = cachemgr.cc \
+       MemBuf.cc \
+       stub_cbdata.cc \
        stub_debug.cc \
+       stub_mem.cc \
        test_tools.cc \
        time.cc
 
index 50b405b394b0f820baa0aa69f714db12d5a9e9bb..5310ced1704c622dd1bee12d07b4f8b246028160 100644 (file)
@@ -35,6 +35,7 @@
 #include "getfullhostname.h"
 #include "html_quote.h"
 #include "ip/Address.h"
+#include "MemBuf.h"
 #include "rfc1123.h"
 #include "rfc1738.h"
 #include "util.h"
@@ -462,8 +463,8 @@ menu_url(cachemgr_request * req, const char *action)
     return url;
 }
 
-static const char *
-munge_menu_line(const char *buf, cachemgr_request * req)
+static void
+munge_menu_line(MemBuf &out, const char *buf, cachemgr_request * req)
 {
     char *x;
     const char *a;
@@ -471,15 +472,14 @@ munge_menu_line(const char *buf, cachemgr_request * req)
     const char *p;
     char *a_url;
     char *buf_copy;
-    static char html[2 * 1024];
 
-    if (strlen(buf) < 1)
-        return buf;
-
-    if (*buf != ' ')
-        return buf;
+    const char bufLen = strlen(buf);
+    if (bufLen < 1 || *buf != ' ') {
+        out.append(buf, bufLen);
+        return;
+    }
 
-    buf_copy = x = xstrdup(buf);
+    buf_copy = x = xstrndup(buf, bufLen);
 
     a = xstrtok(&x, '\t');
 
@@ -491,59 +491,56 @@ munge_menu_line(const char *buf, cachemgr_request * req)
 
     /* no reason to give a url for a disabled action */
     if (!strcmp(p, "disabled"))
-        snprintf(html, sizeof(html), "<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d, a_url);
+        out.Printf("<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d, a_url);
     else
         /* disable a hidden action (requires a password, but password is not in squid.conf) */
         if (!strcmp(p, "hidden"))
-            snprintf(html, sizeof(html), "<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d, a_url);
+            out.Printf("<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d, a_url);
         else
             /* disable link if authentication is required and we have no password */
             if (!strcmp(p, "protected") && !req->passwd)
-                snprintf(html, sizeof(html), "<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n",
-                         d, menu_url(req, "authenticate"), a_url);
+                out.Printf("<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n",
+                           d, menu_url(req, "authenticate"), a_url);
             else
                 /* highlight protected but probably available entries */
                 if (!strcmp(p, "protected"))
-                    snprintf(html, sizeof(html), "<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n",
-                             a_url, d);
+                    out.Printf("<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n",
+                               a_url, d);
 
     /* public entry or unknown type of protection */
                 else
-                    snprintf(html, sizeof(html), "<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url, d);
+                    out.Printf("<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url, d);
 
     xfree(a_url);
 
     xfree(buf_copy);
-
-    return html;
 }
 
-static const char *
-munge_other_line(const char *buf, cachemgr_request * req)
+static void
+munge_other_line(MemBuf &out, const char *buf, cachemgr_request *)
 {
     static const char *ttags[] = {"td", "th"};
 
-    static char html[4096];
     static int table_line_num = 0;
     static int next_is_header = 0;
     int is_header = 0;
     const char *ttag;
     char *buf_copy;
     char *x, *p;
-    int l = 0;
     /* does it look like a table? */
 
     if (!strchr(buf, '\t') || *buf == '\t') {
         /* nope, just text */
-        snprintf(html, sizeof(html), "%s%s",
-                 table_line_num ? "</table>\n<pre>" : "", html_quote(buf));
+        if (table_line_num)
+            out.append("</table>\n<pre>", 14);
+        out.Printf("%s", html_quote(buf));
         table_line_num = 0;
-        return html;
+        return;
     }
 
     /* start html table */
     if (!table_line_num) {
-        l += snprintf(html + l, sizeof(html) - l, "</pre><table cellpadding=\"2\" cellspacing=\"1\">\n");
+        out.append("</pre><table cellpadding=\"2\" cellspacing=\"1\">\n", 46);
         next_is_header = 0;
     }
 
@@ -553,7 +550,7 @@ munge_other_line(const char *buf, cachemgr_request * req)
     ttag = ttags[is_header];
 
     /* record starts */
-    l += snprintf(html + l, sizeof(html) - l, "<tr>");
+    out.append("<tr>", 4);
 
     /* substitute '\t' */
     buf_copy = x = xstrdup(buf);
@@ -570,18 +567,17 @@ munge_other_line(const char *buf, cachemgr_request * req)
             ++x;
         }
 
-        l += snprintf(html + l, sizeof(html) - l, "<%s colspan=\"%d\" align=\"%s\">%s</%s>",
-                      ttag, column_span,
-                      is_header ? "center" : is_number(cell) ? "right" : "left",
-                      html_quote(cell), ttag);
+        out.Printf("<%s colspan=\"%d\" align=\"%s\">%s</%s>",
+                   ttag, column_span,
+                   is_header ? "center" : is_number(cell) ? "right" : "left",
+                   html_quote(cell), ttag);
     }
 
     xfree(buf_copy);
     /* record ends */
-    snprintf(html + l, sizeof(html) - l, "</tr>\n");
+    out.append("</tr>\n", 6);
     next_is_header = is_header && strstr(buf, "\t\t");
     ++table_line_num;
-    return html;
 }
 
 static const char *
@@ -738,14 +734,18 @@ read_reply(int s, cachemgr_request * req)
             /* yes, fall through, we do not want to loose the first line */
 
         case isBody:
+        {
             /* interpret [and reformat] cache response */
-
+            MemBuf out;
+            out.init();
             if (parse_menu)
-                fputs(munge_menu_line(buf, req), stdout);
+                munge_menu_line(out, buf, req);
             else
-                fputs(munge_other_line(buf, req), stdout);
+                munge_other_line(out, buf, req);
 
-            break;
+            fputs(out.buf, stdout);
+        }
+        break;
 
         case isForward:
             /* forward: no modifications allowed */