Florian Obser wrote:
> On Sun, Jul 12, 2020 at 09:10:57AM +0200, Otto Moerbeek wrote:
> > On Sun, Jul 12, 2020 at 09:57:02AM +0430, Ali Farzanrad wrote:
> > 
> > > Hi @tech,
> > > 
> > > I was comparing jsmn.c in acme-client with jsmn.c in FreeBSD [1].
> > > I found a switch without a default case which is an undefined behavior:
> > > 
> > > @@ -69,6 +69,8 @@
> > >                   case '\t' : case '\r' : case '\n' : case ' ' :
> > >                   case ','  : case ']'  : case '}' :
> > >                           goto found;
> > > +                 default:
> > > +                         break;
> > >           }
> > >           if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
> > >                   parser->pos = start;
> > > 
> > > I have patched that undefined behavior + some style fix.
> > 
> > It is bad practise to intermix style changes with bug fixes. 
> > Please post the fix seperately.
> 
> It's also not undefined behaviour.
> ISO/IEC 9899:1999 6.8.4.2:
> 
>       If no converted case constant expression matches and there is no
>       default label, no part of the switch body is executed.

My bad, sorry.

> Not having a default case might be considered bad style in itself
> though.

I also compared it to latest jsmn code, and found out that they have
fixed few other things, like preventing array / object as a key in
another object.

Is it OK to sync in-base jsmn with upstream?  It seems harmless (only
stricter + few style).

(I've attached a single diff, because it is simple sync)


cvs diff: Diffing usr.sbin/acme-client
Index: usr.sbin/acme-client/jsmn.c
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/jsmn.c,v
retrieving revision 1.1
diff -u -p -r1.1 jsmn.c
--- usr.sbin/acme-client/jsmn.c 31 Aug 2016 22:01:42 -0000      1.1
+++ usr.sbin/acme-client/jsmn.c 12 Jul 2020 14:20:06 -0000
@@ -1,31 +1,34 @@
 /*
- Copyright (c) 2010 Serge A. Zaitsev
- 
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- 
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- 
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.*
+ * MIT License
+ *
+ * Copyright (c) 2010 Serge Zaitsev
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
  */
+
 #include "jsmn.h"
 
 /**
- * Allocates a fresh unused token from the token pull.
+ * Allocates a fresh unused token from the token pool.
  */
 static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
-               jsmntok_t *tokens, size_t num_tokens) {
+               jsmntok_t *tokens, const size_t num_tokens) {
        jsmntok_t *tok;
        if (parser->toknext >= num_tokens) {
                return NULL;
@@ -42,8 +45,8 @@ static jsmntok_t *jsmn_alloc_token(jsmn_
 /**
  * Fills token type and boundaries.
  */
-static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
-                            int start, int end) {
+static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type,
+               const int start, const int end) {
        token->type = type;
        token->start = start;
        token->end = end;
@@ -54,7 +57,8 @@ static void jsmn_fill_token(jsmntok_t *t
  * Fills next available token with JSON primitive.
  */
 static int jsmn_parse_primitive(jsmn_parser *parser, const char *js,
-               size_t len, jsmntok_t *tokens, size_t num_tokens) {
+               const size_t len, jsmntok_t *tokens,
+               const size_t num_tokens) {
        jsmntok_t *token;
        int start;
 
@@ -63,12 +67,20 @@ static int jsmn_parse_primitive(jsmn_par
        for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) {
                switch (js[parser->pos]) {
 #ifndef JSMN_STRICT
-                       /* In strict mode primitive must be followed by "," or 
"}" or "]" */
-                       case ':':
+               /* In strict mode primitive must be followed by "," or "}" or 
"]" */
+               case ':':
 #endif
-                       case '\t' : case '\r' : case '\n' : case ' ' :
-                       case ','  : case ']'  : case '}' :
-                               goto found;
+               case '\t':
+               case '\r':
+               case '\n':
+               case ' ':
+               case ',':
+               case ']':
+               case '}':
+                       goto found;
+               default:
+                       /* to quiet a warning from gcc*/
+                       break;
                }
                if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
                        parser->pos = start;
@@ -103,7 +115,8 @@ found:
  * Fills next token with JSON string.
  */
 static int jsmn_parse_string(jsmn_parser *parser, const char *js,
-               size_t len, jsmntok_t *tokens, size_t num_tokens) {
+               const size_t len, jsmntok_t *tokens,
+               const size_t num_tokens) {
        jsmntok_t *token;
 
        int start = parser->pos;
@@ -124,7 +137,7 @@ static int jsmn_parse_string(jsmn_parser
                                parser->pos = start;
                                return JSMN_ERROR_NOMEM;
                        }
-                       jsmn_fill_token(token, JSMN_STRING, start+1, 
parser->pos);
+                       jsmn_fill_token(token, JSMN_STRING, start + 1, 
parser->pos);
 #ifdef JSMN_PARENT_LINKS
                        token->parent = parser->toksuper;
 #endif
@@ -136,29 +149,35 @@ static int jsmn_parse_string(jsmn_parser
                        int i;
                        parser->pos++;
                        switch (js[parser->pos]) {
-                               /* Allowed escaped symbols */
-                               case '\"': case '/' : case '\\' : case 'b' :
-                               case 'f' : case 'r' : case 'n'  : case 't' :
-                                       break;
-                               /* Allows escaped symbol \uXXXX */
-                               case 'u':
-                                       parser->pos++;
-                                       for(i = 0; i < 4 && parser->pos < len 
&& js[parser->pos] != '\0'; i++) {
-                                               /* If it isn't a hex character 
we have an error */
-                                               if(!((js[parser->pos] >= 48 && 
js[parser->pos] <= 57) || /* 0-9 */
-                                                                       
(js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */
-                                                                       
(js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */
-                                                       parser->pos = start;
-                                                       return JSMN_ERROR_INVAL;
-                                               }
-                                               parser->pos++;
+                       /* Allowed escaped symbols */
+                       case '\"':
+                       case '/':
+                       case '\\':
+                       case 'b':
+                       case 'f':
+                       case 'r':
+                       case 'n':
+                       case 't':
+                               break;
+                       /* Allows escaped symbol \uXXXX */
+                       case 'u':
+                               parser->pos++;
+                               for (i = 0; i < 4 && parser->pos < len && 
js[parser->pos] != '\0'; i++) {
+                                       /* If it isn't a hex character we have 
an error */
+                                       if (!((js[parser->pos] >= 48 && 
js[parser->pos] <= 57) || /* 0-9 */
+                                           (js[parser->pos] >= 65 && 
js[parser->pos] <= 70) ||   /* A-F */
+                                           (js[parser->pos] >= 97 && 
js[parser->pos] <= 102))) { /* a-f */
+                                               parser->pos = start;
+                                               return JSMN_ERROR_INVAL;
                                        }
-                                       parser->pos--;
-                                       break;
-                               /* Unexpected symbol */
-                               default:
-                                       parser->pos = start;
-                                       return JSMN_ERROR_INVAL;
+                                       parser->pos++;
+                               }
+                               parser->pos--;
+                               break;
+                       /* Unexpected symbol */
+                       default:
+                               parser->pos = start;
+                               return JSMN_ERROR_INVAL;
                        }
                }
        }
@@ -169,8 +188,8 @@ static int jsmn_parse_string(jsmn_parser
 /**
  * Parse JSON string and fill tokens.
  */
-int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
-               jsmntok_t *tokens, unsigned int num_tokens) {
+int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len,
+               jsmntok_t *tokens, const unsigned int num_tokens) {
        int r;
        int i;
        jsmntok_t *token;
@@ -182,128 +201,164 @@ int jsmn_parse(jsmn_parser *parser, cons
 
                c = js[parser->pos];
                switch (c) {
-                       case '{': case '[':
-                               count++;
-                               if (tokens == NULL) {
-                                       break;
+               case '{':
+               case '[':
+                       count++;
+                       if (tokens == NULL) {
+                               break;
+                       }
+                       token = jsmn_alloc_token(parser, tokens, num_tokens);
+                       if (token == NULL) {
+                               return JSMN_ERROR_NOMEM;
+                       }
+                       if (parser->toksuper != -1) {
+                               jsmntok_t *t = &tokens[parser->toksuper];
+#ifdef JSMN_STRICT
+                               /* In strict mode an object or array can't 
become a key */
+                               if (t->type == JSMN_OBJECT) {
+                                       return JSMN_ERROR_INVAL;
                                }
-                               token = jsmn_alloc_token(parser, tokens, 
num_tokens);
-                               if (token == NULL)
-                                       return JSMN_ERROR_NOMEM;
-                               if (parser->toksuper != -1) {
-                                       tokens[parser->toksuper].size++;
+#endif
+                               t->size++;
 #ifdef JSMN_PARENT_LINKS
-                                       token->parent = parser->toksuper;
+                               token->parent = parser->toksuper;
 #endif
-                               }
-                               token->type = (c == '{' ? JSMN_OBJECT : 
JSMN_ARRAY);
-                               token->start = parser->pos;
-                               parser->toksuper = parser->toknext - 1;
+                       }
+                       token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
+                       token->start = parser->pos;
+                       parser->toksuper = parser->toknext - 1;
+                       break;
+               case '}':
+               case ']':
+                       if (tokens == NULL) {
                                break;
-                       case '}': case ']':
-                               if (tokens == NULL)
-                                       break;
-                               type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
+                       }
+                       type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
 #ifdef JSMN_PARENT_LINKS
-                               if (parser->toknext < 1) {
-                                       return JSMN_ERROR_INVAL;
-                               }
-                               token = &tokens[parser->toknext - 1];
-                               for (;;) {
-                                       if (token->start != -1 && token->end == 
-1) {
-                                               if (token->type != type) {
-                                                       return JSMN_ERROR_INVAL;
-                                               }
-                                               token->end = parser->pos + 1;
-                                               parser->toksuper = 
token->parent;
-                                               break;
+                       if (parser->toknext < 1) {
+                               return JSMN_ERROR_INVAL;
+                       }
+                       token = &tokens[parser->toknext - 1];
+                       for (;;) {
+                               if (token->start != -1 && token->end == -1) {
+                                       if (token->type != type) {
+                                               return JSMN_ERROR_INVAL;
                                        }
-                                       if (token->parent == -1) {
-                                               break;
+                                       token->end = parser->pos + 1;
+                                       parser->toksuper = token->parent;
+                                       break;
+                               }
+                               if (token->parent == -1) {
+                                       if (token->type != type || 
parser->toksuper == -1) {
+                                               return JSMN_ERROR_INVAL;
                                        }
-                                       token = &tokens[token->parent];
+                                       break;
                                }
+                               token = &tokens[token->parent];
+                       }
 #else
-                               for (i = parser->toknext - 1; i >= 0; i--) {
-                                       token = &tokens[i];
-                                       if (token->start != -1 && token->end == 
-1) {
-                                               if (token->type != type) {
-                                                       return JSMN_ERROR_INVAL;
-                                               }
-                                               parser->toksuper = -1;
-                                               token->end = parser->pos + 1;
-                                               break;
+                       for (i = parser->toknext - 1; i >= 0; i--) {
+                               token = &tokens[i];
+                               if (token->start != -1 && token->end == -1) {
+                                       if (token->type != type) {
+                                               return JSMN_ERROR_INVAL;
                                        }
+                                       parser->toksuper = -1;
+                                       token->end = parser->pos + 1;
+                                       break;
                                }
-                               /* Error if unmatched closing bracket */
-                               if (i == -1) return JSMN_ERROR_INVAL;
-                               for (; i >= 0; i--) {
-                                       token = &tokens[i];
-                                       if (token->start != -1 && token->end == 
-1) {
-                                               parser->toksuper = i;
-                                               break;
-                                       }
+                       }
+                       /* Error if unmatched closing bracket */
+                       if (i == -1) {
+                               return JSMN_ERROR_INVAL;
+                       }
+                       for (; i >= 0; i--) {
+                               token = &tokens[i];
+                               if (token->start != -1 && token->end == -1) {
+                                       parser->toksuper = i;
+                                       break;
                                }
+                       }
 #endif
-                               break;
-                       case '\"':
-                               r = jsmn_parse_string(parser, js, len, tokens, 
num_tokens);
-                               if (r < 0) return r;
-                               count++;
-                               if (parser->toksuper != -1 && tokens != NULL)
-                                       tokens[parser->toksuper].size++;
-                               break;
-                       case '\t' : case '\r' : case '\n' : case ' ':
-                               break;
-                       case ':':
-                               parser->toksuper = parser->toknext - 1;
-                               break;
-                       case ',':
-                               if (tokens != NULL && parser->toksuper != -1 &&
-                                               tokens[parser->toksuper].type 
!= JSMN_ARRAY &&
-                                               tokens[parser->toksuper].type 
!= JSMN_OBJECT) {
+                       break;
+               case '\"':
+                       r = jsmn_parse_string(parser, js, len, tokens, 
num_tokens);
+                       if (r < 0) {
+                               return r;
+                       }
+                       count++;
+                       if (parser->toksuper != -1 && tokens != NULL) {
+                               tokens[parser->toksuper].size++;
+                       }
+                       break;
+               case '\t':
+               case '\r':
+               case '\n':
+               case ' ':
+                       break;
+               case ':':
+                       parser->toksuper = parser->toknext - 1;
+                       break;
+               case ',':
+                       if (tokens != NULL && parser->toksuper != -1 &&
+                           tokens[parser->toksuper].type != JSMN_ARRAY &&
+                           tokens[parser->toksuper].type != JSMN_OBJECT) {
 #ifdef JSMN_PARENT_LINKS
-                                       parser->toksuper = 
tokens[parser->toksuper].parent;
+                               parser->toksuper = 
tokens[parser->toksuper].parent;
 #else
-                                       for (i = parser->toknext - 1; i >= 0; 
i--) {
-                                               if (tokens[i].type == 
JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) {
-                                                       if (tokens[i].start != 
-1 && tokens[i].end == -1) {
-                                                               
parser->toksuper = i;
-                                                               break;
-                                                       }
+                               for (i = parser->toknext - 1; i >= 0; i--) {
+                                       if (tokens[i].type == JSMN_ARRAY || 
tokens[i].type == JSMN_OBJECT) {
+                                               if (tokens[i].start != -1 && 
tokens[i].end == -1) {
+                                                       parser->toksuper = i;
+                                                       break;
                                                }
                                        }
-#endif
                                }
-                               break;
+#endif
+                       }
+                       break;
 #ifdef JSMN_STRICT
-                       /* In strict mode primitives are: numbers and booleans 
*/
-                       case '-': case '0': case '1' : case '2': case '3' : 
case '4':
-                       case '5': case '6': case '7' : case '8': case '9':
-                       case 't': case 'f': case 'n' :
-                               /* And they must not be keys of the object */
-                               if (tokens != NULL && parser->toksuper != -1) {
-                                       jsmntok_t *t = 
&tokens[parser->toksuper];
-                                       if (t->type == JSMN_OBJECT ||
-                                                       (t->type == JSMN_STRING 
&& t->size != 0)) {
-                                               return JSMN_ERROR_INVAL;
-                                       }
+               /* In strict mode primitives are: numbers and booleans */
+               case '-':
+               case '0':
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+               case 't':
+               case 'f':
+               case 'n':
+                       /* And they must not be keys of the object */
+                       if (tokens != NULL && parser->toksuper != -1) {
+                               const jsmntok_t *t = &tokens[parser->toksuper];
+                               if (t->type == JSMN_OBJECT ||
+                                   (t->type == JSMN_STRING && t->size != 0)) {
+                                       return JSMN_ERROR_INVAL;
                                }
+                       }
 #else
-                       /* In non-strict mode every unquoted value is a 
primitive */
-                       default:
+               /* In non-strict mode every unquoted value is a primitive */
+               default:
 #endif
-                               r = jsmn_parse_primitive(parser, js, len, 
tokens, num_tokens);
-                               if (r < 0) return r;
-                               count++;
-                               if (parser->toksuper != -1 && tokens != NULL)
-                                       tokens[parser->toksuper].size++;
-                               break;
+                       r = jsmn_parse_primitive(parser, js, len, tokens, 
num_tokens);
+                       if (r < 0) {
+                               return r;
+                       }
+                       count++;
+                       if (parser->toksuper != -1 && tokens != NULL) {
+                               tokens[parser->toksuper].size++;
+                       }
+                       break;
 
 #ifdef JSMN_STRICT
-                       /* Unexpected char in strict mode */
-                       default:
-                               return JSMN_ERROR_INVAL;
+               /* Unexpected char in strict mode */
+               default:
+                       return JSMN_ERROR_INVAL;
 #endif
                }
        }
@@ -321,7 +376,7 @@ int jsmn_parse(jsmn_parser *parser, cons
 }
 
 /**
- * Creates a new parser based over a given  buffer with an array of tokens
+ * Creates a new parser based over a given buffer with an array of tokens
  * available.
  */
 void jsmn_init(jsmn_parser *parser) {
Index: usr.sbin/acme-client/jsmn.h
===================================================================
RCS file: /cvs/src/usr.sbin/acme-client/jsmn.h,v
retrieving revision 1.1
diff -u -p -r1.1 jsmn.h
--- usr.sbin/acme-client/jsmn.h 31 Aug 2016 22:01:42 -0000      1.1
+++ usr.sbin/acme-client/jsmn.h 12 Jul 2020 14:15:20 -0000
@@ -1,23 +1,25 @@
 /*
- Copyright (c) 2010 Serge A. Zaitsev
- 
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- 
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- 
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.*
+ * MIT License
+ *
+ * Copyright (c) 2010 Serge Zaitsev
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
  */
 #ifndef __JSMN_H_
 #define __JSMN_H_
@@ -54,11 +56,11 @@ enum jsmnerr {
 
 /**
  * JSON token description.
- * @param              type    type (object, array, string etc.)
- * @param              start   start position in JSON data string
- * @param              end             end position in JSON data string
+ * type                type (object, array, string etc.)
+ * start       start position in JSON data string
+ * end         end position in JSON data string
  */
-typedef struct {
+typedef struct jsmntok {
        jsmntype_t type;
        int start;
        int end;
@@ -70,12 +72,12 @@ typedef struct {
 
 /**
  * JSON parser. Contains an array of token blocks available. Also stores
- * the string being parsed now and current position in that string
+ * the string being parsed now and current position in that string.
  */
-typedef struct {
-       unsigned int pos; /* offset in the JSON string */
+typedef struct jsmn_parser {
+       unsigned int pos;     /* offset in the JSON string */
        unsigned int toknext; /* next token to allocate */
-       int toksuper; /* superior token node, e.g parent object or array */
+       int toksuper;         /* superior token node, e.g. parent object or 
array */
 } jsmn_parser;
 
 /**
@@ -84,11 +86,11 @@ typedef struct {
 void jsmn_init(jsmn_parser *parser);
 
 /**
- * Run JSON parser. It parses a JSON data string into and array of tokens, 
each describing
- * a single JSON object.
+ * Run JSON parser. It parses a JSON data string into and array of tokens, each
+ * describing a single JSON object.
  */
-int jsmn_parse(jsmn_parser *parser, const char *js, size_t len,
-               jsmntok_t *tokens, unsigned int num_tokens);
+int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len,
+               jsmntok_t *tokens, const unsigned int num_tokens);
 
 #ifdef __cplusplus
 }

Reply via email to