apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From david reid <da...@jetnet.co.uk>
Subject apr_quote
Date Wed, 02 Aug 2006 13:18:46 GMT
More code taken from apreq - this time more modified to fit with apr and
even with a test case!

Really out the door this time :-)

Index: include/apr_strings.h
===================================================================
--- include/apr_strings.h       (revision 416632)
+++ include/apr_strings.h       (working copy)
@@ -348,6 +348,35 @@
  */
 APR_DECLARE(char *) apr_strfsize(apr_off_t size, char *buf);

+/**
+ * @fn apr_status_t apr_quote_once(char **dest, const char *src,
+                                    const apr_size_t slen,
+                                    apr_pool_t *pool)
+ * @brief Quote the supplied string. This fucntion will check to see if
+ *        the string is already quoted before applying changes. It will
+ *        always return a copy of the string in *dest;
+ * @param dest pointer to the pointer to the returned string
+ * @param src string to be quoted
+ * @param slen length of string to be quoted
+ * @param pool the pool to use for memory allocation
+ */
+APR_DECLARE(apr_status_t) apr_quote_once(char **, const char *,
+                                         const apr_size_t, apr_pool_t *);
+
+
+/**
+ * @fn apr_status_t apr_quote(char **dest, const char *src,
+                                    const apr_size_t slen,
+                                    apr_pool_t *pool)
+ * @brief Quote the supplied string.
+ * @param dest pointer to the pointer to the returned string
+ * @param src string to be quoted
+ * @param slen length of string to be quoted
+ * @param pool the pool to use for memory allocation
+ */
+APR_DECLARE(apr_status_t) apr_quote(char **, const char *,
+                                    const apr_size_t, apr_pool_t *);
+
 /** @} */

Index: test/teststr.c
===================================================================
--- test/teststr.c      (revision 416903)
+++ test/teststr.c      (working copy)
@@ -363,6 +363,25 @@
     ABTS_TRUE(tc, ret[1] == 'Z');
 }

+static void string_quote(abts_case *tc, void *data)
+{
+    char *plain = "hello \"world\"";
+    char *quoted = NULL, *qquoted = NULL;
+    int rv;
+    char *res = "\"\\\"hello \\\\\\\"world\\\\\\\"\\\"\"";
+
+    rv = apr_quote(&quoted, plain, 13, p);
+    ABTS_INT_EQUAL(tc, rv, APR_SUCCESS);
+    ABTS_STR_EQUAL(tc, "\"hello \\\"world\\\"\"", quoted);
+    rv = apr_quote_once(&qquoted, quoted, 17, p);
+    ABTS_INT_EQUAL(tc, rv, APR_SUCCESS);
+    ABTS_STR_EQUAL(tc, "\"hello \\\"world\\\"\"", qquoted);
+    rv = apr_quote(&qquoted, quoted, 17, p);
+    ABTS_INT_EQUAL(tc, rv, APR_SUCCESS);
+    ABTS_STR_EQUAL(tc, res, qquoted);
+
+}
+
 abts_suite *teststr(abts_suite *suite)
 {
     suite = ADD_SUITE(suite)
@@ -379,6 +398,7 @@
     abts_run_test(suite, overflow_strfsize, NULL);
     abts_run_test(suite, string_strfsize, NULL);
     abts_run_test(suite, string_cpystrn, NULL);
+    abts_run_test(suite, string_quote, NULL);

     return suite;
 }

--- strings/apr_quote.c (revision 0)
+++ strings/apr_quote.c (revision 0)
@@ -0,0 +1,106 @@
+/* Copyright 2006 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr.h"
+#include "apr_strings.h"
+#include "apr_private.h"
+#include "apr_lib.h"
+
+#if APR_HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if APR_HAVE_STRING_H
+#include <string.h>
+#endif
+#if APR_HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+static int is_quoted(const char *p, const apr_size_t len)
+{
+    if (len > 1 && p[0] == '"' && p[len-1] == '"') {
+        apr_size_t i;
+        int backslash = 0;
+
+        for (i = 1; i < len - 1; i++) {
+            if (p[i] == '\\')
+                backslash = !backslash;
+            else if (p[i] == 0 || (p[i] == '"' && !backslash))
+                return 0;
+            else
+                backslash = 0;
+        }
+
+        return !backslash;
+    }
+
+    return 0;
+}
+
+APR_DECLARE(apr_status_t) apr_quote_once(char **dest,
+                                         const char *src,
+                                         const apr_size_t slen,
+                                         apr_pool_t *pool)
+{
+    if (is_quoted(src, slen)) {
+        *dest = apr_pstrndup(pool, src, slen);
+        return APR_SUCCESS;
+    }
+    return apr_quote(dest, src, slen, pool);
+}
+
+APR_DECLARE(apr_status_t) apr_quote(char **dest, const char *src,
+                                    const apr_size_t slen,
+                                    apr_pool_t *pool)
+{
+    char *d = *dest;
+    const char *s = src;
+    const char *const last = src + slen - 1;
+    int needed = 0;
+
+    *dest = NULL;
+    if (slen == 0)
+        return APR_EINVAL;
+
+    /* 2 pass - messy - better ways? */
+    while (s <= last) {
+        if (*s == '\\' || *s == '"' || *s == 0)
+            needed++;
+        s++;
+    }
+
+    *dest = (char *)apr_pcalloc(pool, slen + needed + 3);
+    d = *dest;
+    s = src;
+    *d++ = '"';
+    while (s <= last) {
+        switch (*s) {
+            case 0:
+                *d++ = '\\';
+                *d++ = '0';
+                s++;
+                break;
+            case '\\':
+            case '"':
+                *d++ = '\\';
+            default:
+                *d++ = *s++;
+        }
+    }
+    *d++ = '"';
+
+    return APR_SUCCESS;
+}


-- 
david

http://feathercast.org/

Mime
View raw message