]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add function to print VP values as JSON strings
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 24 Oct 2011 11:20:39 +0000 (13:20 +0200)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 25 Oct 2011 21:58:45 +0000 (23:58 +0200)
src/include/libradius.h
src/lib/print.c

index fa438a0b0a0a98e61ccf5a22212fa08946e42c96..0a2effdbfcc65b1421ec6513fbfccebd5fc5d8cd 100644 (file)
@@ -256,6 +256,8 @@ size_t              fr_print_string(const char *in, size_t inlen,
                                 char *out, size_t outlen);
 int            vp_prints_value(char *out, size_t outlen,
                                const VALUE_PAIR *vp, int delimitst);
+int            vp_prints_value_json(char *out, size_t outlen,
+                               const VALUE_PAIR *vp);
 size_t         vp_print_name(char *buffer, size_t bufsize,
                               unsigned int attr, unsigned int vendor);
 int            vp_prints(char *out, size_t outlen, const VALUE_PAIR *vp);
index 20985282fea4f56d313102d367b101c369793c7d..a0d4498484c8a794a8d748af2a77cd19314e1a71 100644 (file)
@@ -362,6 +362,86 @@ int vp_prints_value(char * out, size_t outlen, const VALUE_PAIR *vp, int delimit
        return strlen(out);
 }
 
+/*
+ *  Almost identical to vp_prints_value, but escapes certain chars so the string
+ *  may be used as a JSON value.
+ *
+ *  Returns < 0 if the buffer may be (or have been) too small to write the encoded
+ *  JSON value to.
+ */
+int vp_prints_value_json(char *buffer, size_t bufsize, const VALUE_PAIR *vp)
+{
+       int s = 0;
+       char *p = buffer;
+       const char *q;
+       if (!vp->flags.has_tag) {
+               switch (vp->type) {
+                       case PW_TYPE_INTEGER:
+                       case PW_TYPE_BYTE:
+                       case PW_TYPE_SHORT:
+                               if (vp->flags.has_value) break;
+                               
+                               s = snprintf(buffer, bufsize, "%u", vp->vp_integer);
+                               return ((unsigned) s == (bufsize - 1)) ? -1 : s;
+                       case PW_TYPE_SIGNED:
+                               s = snprintf(buffer, bufsize, "%d", vp->vp_signed);
+                               return ((unsigned) s == (bufsize - 1)) ? -1 : s;
+               }
+       }
+
+       if(bufsize < 3) return -1;
+       *p++ = '"';
+
+       switch (vp->type) {
+               case PW_TYPE_STRING:
+                       for (q = vp->vp_strvalue; q < vp->vp_strvalue + vp->length; q++) {
+                               s = bufsize - (p - buffer);
+                               if (s < 3) return -1;
+                               
+                               if (*q == '"') {
+                                       *p++ = '\\';
+                                       *p++ = '"';
+                               } else if (*q == '\\') {
+                                       *p++ = '\\';
+                                       *p++ = '\\';
+                               } else if (*q == '/') {
+                                       *p++ = '\\';
+                                       *p++ = '/';
+                               } else if (*q >= ' ') {
+                                       *p++ = *q;
+                               } else {
+                                       *p++ = '\\';
+                                       
+                                       if (*q == '\b') {
+                                               *p++ = 'b';
+                                       } else if (*q == '\f') {
+                                               *p++ = 'f';
+                                       } else if (*q == '\n') {
+                                               *p++ = 'n';
+                                       } else if (*q == '\r') {
+                                               *p++ = 'r';
+                                       } else if (*q == '\t'){ 
+                                               *p++ = 't';
+                                       } else {
+                                               if(s < 7) return -1;
+                                               *p += sprintf(p, "u%04X", *q);
+                                       }
+                               }
+                       }
+                       break;
+
+               default:
+                       p += vp_prints_value(p, bufsize, vp, 0);
+                       break;
+       }
+
+       *p++ = '"';
+       *p = '\0';
+   
+       return p - buffer;
+}
+
 /*
  *  This is a hack, and has to be kept in sync with tokens.h
  */