--- a/json.c
+++ b/json.c
@@ -30,7 +30,7 @@ will match the right spec against the ac
 recognize the JSON "null" value.  Secondly, arrays may not have
 character values as elements (this limitation could be easily removed
 if required). Third, all elements of an array must be of the same
-type.
+type.  Fourth, it can not handle NaN's in doubles (Issue 53150).
 
    There are separate entry points for beginning a parse of either
 JSON object or a JSON array. JSON "float" quantities are actually
@@ -59,7 +59,7 @@ reusable module; search for "microjson".
 
 PERMISSIONS
    This file is Copyright (c) 2010 by the GPSD project
-   BSD terms apply: see the file COPYING in the distribution root for details.
+   SPDX-License-Identifier: BSD-2-clause
 
 ***************************************************************************/
 #include <stdio.h>
@@ -188,7 +188,7 @@ static int json_internal_read_object(con
     char *lptr;
 
     if (end != NULL)
-	*end = NULL;		/* give it a well-defined value on parse failure */
+	*end = NULL;	/* give it a well-defined value on parse failure */
 
     /* stuff fields with defaults in case they're omitted in the JSON input */
     for (cursor = attrs; cursor->attribute != NULL; cursor++)
@@ -294,7 +294,8 @@ static int json_internal_read_object(con
 		}
 		if (cursor->attribute == NULL) {
 		    json_debug_trace((1,
-				      "Unknown attribute name '%s' (attributes begin with '%s').\n",
+				      "Unknown attribute name '%s'"
+                                      " (attributes begin with '%s').\n",
 				      attrbuf, attrs->attribute));
 		    /* don't update end here, leave at attribute start */
 		    return JSON_ERR_BADATTR;
@@ -374,6 +375,12 @@ static int json_internal_read_object(con
 	    if (pval == NULL)
 		/* don't update end here, leave at value start */
 		return JSON_ERR_NULLPTR;
+	    else if (pval > valbuf + JSON_VAL_MAX - 1
+		       || pval > valbuf + maxlen) {
+		json_debug_trace((1, "String value too long.\n"));
+		/* don't update end here, leave at value start */
+		return JSON_ERR_STRLONG;	/*  */
+	    }
 	    switch (*cp) {
 	    case 'b':
 		*pval++ = '\b';
@@ -391,11 +398,16 @@ static int json_internal_read_object(con
 		*pval++ = '\t';
 		break;
 	    case 'u':
-		for (n = 0; n < 4 && cp[n] != '\0'; n++)
+                cp++;                   /* skip the 'u' */
+		for (n = 0; n < 4 && isxdigit(*cp); n++)
 		    uescape[n] = *cp++;
+                uescape[n] = '\0';      /* terminate */
 		--cp;
-		(void)sscanf(uescape, "%04x", &u);
-		*pval++ = (char)u;	/* will truncate values above 0xff */
+                /* ECMA-404 says JSON \u must have 4 hex digits */
+		if ((4 != n) || (1 != sscanf(uescape, "%4x", &u))) {
+		    return JSON_ERR_BADSTRING;
+                }
+		*pval++ = (unsigned char)u;  /* truncate values above 0xff */
 		break;
 	    default:		/* handles double quote and solidus */
 		*pval++ = *cp;
@@ -432,7 +444,8 @@ static int json_internal_read_object(con
 	     */
 	    for (;;) {
 		int seeking = cursor->type;
-		if (value_quoted && (cursor->type == t_string || cursor->type == t_time))
+		if (value_quoted && (cursor->type == t_string
+                    || cursor->type == t_time))
 		    break;
 		if ((strcmp(valbuf, "true")==0 || strcmp(valbuf, "false")==0)
 			&& seeking == t_boolean)
@@ -441,7 +454,8 @@ static int json_internal_read_object(con
 		    bool decimal = strchr(valbuf, '.') != NULL;
 		    if (decimal && seeking == t_real)
 			break;
-		    if (!decimal && (seeking == t_integer || seeking == t_uinteger))
+		    if (!decimal && (seeking == t_integer
+                                     || seeking == t_uinteger))
 			break;
 		}
 		if (cursor[1].attribute==NULL)	/* out of possiblities */
@@ -454,15 +468,15 @@ static int json_internal_read_object(con
 		&& (cursor->type != t_string && cursor->type != t_character
 		    && cursor->type != t_check && cursor->type != t_time
 		    && cursor->type != t_ignore && cursor->map == 0)) {
-		json_debug_trace((1,
-				  "Saw quoted value when expecting non-string.\n"));
+		json_debug_trace((1, "Saw quoted value when expecting"
+                                  " non-string.\n"));
 		return JSON_ERR_QNONSTRING;
 	    }
 	    if (!value_quoted
 		&& (cursor->type == t_string || cursor->type == t_check
 		    || cursor->type == t_time || cursor->map != 0)) {
-		json_debug_trace((1,
-				  "Didn't see quoted value when expecting string.\n"));
+		json_debug_trace((1, "Didn't see quoted value when expecting"
+                                  " string.\n"));
 		return JSON_ERR_NONQSTRING;
 	    }
 	    if (cursor->map != 0) {
@@ -542,14 +556,15 @@ static int json_internal_read_object(con
 		    break;
 		case t_check:
 		    if (strcmp(cursor->dflt.check, valbuf) != 0) {
-			json_debug_trace((1,
-					  "Required attribute value %s not present.\n",
+			json_debug_trace((1, "Required attribute value %s"
+                                          " not present.\n",
 					  cursor->dflt.check));
 			/* don't update end here, leave at start of attribute */
 			return JSON_ERR_CHECKFAIL;
 		    }
 		    break;
 		}
+	    __attribute__ ((fallthrough));
 	case post_array:
 	    if (isspace((unsigned char) *cp))
 		continue;
@@ -587,7 +602,7 @@ int json_read_array(const char *cp, cons
     char *tp;
 
     if (end != NULL)
-	*end = NULL;		/* give it a well-defined value on parse failure */
+	*end = NULL;	/* give it a well-defined value on parse failure */
 
     json_debug_trace((1, "Entered json_read_array()\n"));
 
@@ -663,7 +678,8 @@ int json_read_array(const char *cp, cons
 #endif /* JSON_MINIMAL */
 	case t_uinteger:
 #ifndef JSON_MINIMAL
-	    arr->arr.uintegers.store[offset] = (unsigned int)strtoul(cp, &ep, 0);
+	    arr->arr.uintegers.store[offset] = (unsigned int)strtoul(cp,
+                                                                     &ep, 0);
 	    if (ep == cp)
 		return JSON_ERR_BADNUM;
 	    else
@@ -681,7 +697,8 @@ int json_read_array(const char *cp, cons
 #endif /* JSON_MINIMAL */
 	case t_ushort:
 #ifndef JSON_MINIMAL
-	    arr->arr.ushorts.store[offset] = (unsigned short)strtoul(cp, &ep, 0);
+	    arr->arr.ushorts.store[offset] = (unsigned short)strtoul(cp,
+                                                                     &ep, 0);
 	    if (ep == cp)
 		return JSON_ERR_BADNUM;
 	    else
--- a/json.h
+++ b/json.h
@@ -1,7 +1,7 @@
 /* Structures for JSON parsing using only fixed-extent memory
  *
  * This file is Copyright (c) 2010 by the GPSD project
- * BSD terms apply: see the file COPYING in the distribution root for details.
+ * SPDX-License-Identifier: BSD-2-clause
  */
 
 #include <stdbool.h>
