@@ -773,6 +773,83 @@ store_attrs(struct ly_ctx *ctx, struct attr_cont *attrs, struct lyd_node *first,
773773 return -1 ;
774774}
775775
776+ /**
777+ * @brief Skip subtree (find its end in the input data) of the current JSON item.
778+ * @param[in] ctx libyang context for logging
779+ * @param[in] parent parent node for logging
780+ * @param[in] data input data (pointing to the beginning, @p len is used to go to the current position).
781+ * @param[in, out] len Current position in the @p data, will be updated to the end of the element's subtree in the @p data
782+ * @retun 0 on success
783+ * @return -1 on error.
784+ */
785+ static int
786+ json_skip_unknown (struct ly_ctx * ctx , struct lyd_node * parent , const char * data , unsigned int * len )
787+ {
788+ int qstr = 0 ;
789+ int objects = 0 ;
790+ int arrays = 0 ;
791+
792+ while (data [* len ]) {
793+ switch (data [* len ]) {
794+ case '\"' :
795+ if (qstr ) {
796+ if (data [(* len ) - 1 ] != '\\' ) {
797+ qstr = 0 ;
798+ }
799+ } else if (data [(* len ) - 1 ] != '\\' ) {
800+ qstr = 1 ;
801+ } else {
802+ LOGVAL (ctx , LYE_INVAL , LY_VLOG_LYD , parent , "JSON data (missing quotation mark for a string data) " );
803+ return -1 ;
804+ }
805+ break ;
806+ case '[' :
807+ if (!qstr ) {
808+ arrays ++ ;
809+ }
810+ break ;
811+ case '{' :
812+ if (!qstr ) {
813+ objects ++ ;
814+ }
815+ break ;
816+ case ']' :
817+ if (!qstr ) {
818+ arrays -- ;
819+ }
820+ break ;
821+ case '}' :
822+ if (!qstr ) {
823+ objects -- ;
824+ }
825+ break ;
826+ case ',' :
827+ if (!qstr && !objects && !arrays ) {
828+ /* do not eat the comma character */
829+ return 0 ;
830+ }
831+ }
832+
833+ if (objects < 0 ) {
834+ if (arrays ) {
835+ LOGVAL (ctx , LYE_XML_INVAL , LY_VLOG_LYD , parent , "JSON data (missing end-array)" );
836+ return -1 ;
837+ }
838+ return 0 ;
839+ }
840+ if (arrays < 0 ) {
841+ if (objects ) {
842+ LOGVAL (ctx , LYE_XML_INVAL , LY_VLOG_LYD , parent , "JSON data (missing end-object)" );
843+ return -1 ;
844+ }
845+ return 0 ;
846+ }
847+ (* len )++ ;
848+ }
849+
850+ return 0 ;
851+ }
852+
776853static unsigned int
777854json_parse_data (struct ly_ctx * ctx , const char * data , const struct lys_node * schema_parent , struct lyd_node * * parent ,
778855 struct lyd_node * first_sibling , struct lyd_node * prev , struct attr_cont * * attrs , int options ,
@@ -943,8 +1020,16 @@ json_parse_data(struct ly_ctx *ctx, const char *data, const struct lys_node *sch
9431020
9441021 module = lys_node_module (schema );
9451022 if (!module || !module -> implemented || module -> disabled ) {
946- LOGVAL (ctx , LYE_INELEM , (* parent ? LY_VLOG_LYD : LY_VLOG_NONE ), (* parent ), name );
947- goto error ;
1023+ if (options & LYD_OPT_STRICT ) {
1024+ LOGVAL (ctx , LYE_INELEM , (* parent ? LY_VLOG_LYD : LY_VLOG_NONE ), (* parent ), name );
1025+ goto error ;
1026+ } else {
1027+ if (json_skip_unknown (ctx , * parent , data , & len )) {
1028+ goto error ;
1029+ }
1030+ free (str );
1031+ return len ;
1032+ }
9481033 }
9491034
9501035 if (str [0 ] == '@' ) {
0 commit comments