Fix Json allowing permissive parsing.
authorLee Morgan <Lee.morgan@partner.samsung.com>
Mon, 28 Apr 2014 13:56:10 +0000 (14:56 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 15 May 2014 11:54:13 +0000 (12:54 +0100)
[Issue] N/A

[Problem] Allowing non standard JSON. (aside from comments)

[Cause] N/A

[Solution] N/A

Change-Id: I5fcf3c5d2bfcc51e3e15a251263f6a9cb9b9627b
Signed-off-by: Lee Morgan <Lee.morgan@partner.samsung.com>
automated-tests/src/dali-toolkit-unmanaged/utc-Dali-JsonParser.cpp
optional/dali-toolkit/internal/builder/json-parser-state.cpp
optional/dali-toolkit/internal/builder/optional-value.h
optional/dali-toolkit/internal/builder/tree-node-manipulator.cpp

index 4864733..07291a3 100644 (file)
@@ -43,6 +43,56 @@ std::string ReplaceQuotes(const std::string &in_s)
   std::replace(s.begin(), s.end(), '\'', '"');
   return s;
 }
+
+void CompareTrees(const TreeNode& a, const TreeNode& b)
+{
+  DALI_TEST_CHECK( a.GetType() == b.GetType() );
+
+  DALI_TEST_CHECK( a.Size() == b.Size() );
+
+  if( a.GetName() )
+  {
+    DALI_TEST_CHECK( std::string( a.GetName() ) == std::string( b.GetName() ) );
+  }
+
+  DALI_TEST_CHECK( a.HasSubstitution() == b.HasSubstitution() );
+
+  switch( a.GetType() )
+  {
+    case TreeNode::OBJECT:
+    case TreeNode::ARRAY:
+    {
+      for( TreeNode::ConstIterator aiter = a.CBegin(), biter = b.CBegin();
+           aiter != a.CEnd() && biter != b.CEnd(); ++aiter, ++biter )
+      {
+        CompareTrees( (*aiter).second, (*biter).second );
+      }
+      break;
+    }
+    case TreeNode::STRING:
+    {
+      DALI_TEST_CHECK( std::string( a.GetString() ) == std::string( b.GetString() ) );
+      break;
+    }
+    case TreeNode::FLOAT:
+    {
+      DALI_TEST_CHECK( a.GetFloat() == b.GetFloat() );
+      break;
+    }
+    case TreeNode::INTEGER:
+    {
+      DALI_TEST_CHECK( a.GetInteger() == b.GetInteger());
+      break;
+    }
+    case TreeNode::BOOLEAN:
+    {
+      DALI_TEST_CHECK( a.GetBoolean() == b.GetBoolean() );
+      break;
+    }
+  }
+}
+
+
 }
 
 
@@ -61,7 +111,6 @@ int UtcDaliJsonParserMethod01(void)
   'nil':null, \
   'array':[1,2,3], \
   'object':{'key':'value'} \
-END_TEST; \
 }"));
 
   JsonParser parser = JsonParser::New();
@@ -468,7 +517,7 @@ int UtcDaliJsonParserMethod06(void)
 namespace
 {
 
-static const int NUMBER_FAIL_TESTS = 32;
+static const int NUMBER_FAIL_TESTS = 34;
 const char *TEST_FAIL[] = {
   "[' tab\t   character  \t in\t string   ']",
   "['Extra close']]",
@@ -502,6 +551,8 @@ const char *TEST_FAIL[] = {
   "[0e+-1]",
   "{'Numbers cannot be hex': 0x14}",
   "[   , '<-- missing value']",
+  "[{'no comma':1} {'b:2}]",
+  "{'extra comma':1,}",
 };
 }
 
@@ -612,7 +663,7 @@ int UtcDaliJsonParserMethod10(void)
 {
   ToolkitTestApplication application;
 
-  tet_infoline("JSON basic test");
+  tet_infoline("JSON empty data");
 
   std::string s1( "" );
 
@@ -625,3 +676,44 @@ int UtcDaliJsonParserMethod10(void)
   tet_result(TET_PASS);
   END_TEST;
 }
+
+int UtcDaliJsonParserMethod11(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("JSON tree copy");
+
+  std::string s1( ReplaceQuotes("                                       \
+{                                                                       \
+  'animations':                                                         \
+  {                                                                     \
+    'bump':                                                             \
+    {                                                                   \
+      'properties':                                                     \
+      [                                                                 \
+        {                                                               \
+          'actor':'bump-image',                                         \
+          'property':'uLightPosition',                                  \
+          'value':[0.8, 0.0, -1.5],                                     \
+          'alpha-function': 'BOUNCE',                                   \
+          'time-period': { 'duration': 2.5 }                            \
+        }                                                               \
+      ]                                                                 \
+    }                                                                   \
+  }                                                                     \
+}                                                                       \
+"));
+
+  JsonParser parser = JsonParser::New();
+
+  parser.Parse( s1 );
+
+  JsonParser parser2 = JsonParser::New(*parser.GetRoot());
+
+  DALI_TEST_CHECK(parser.GetRoot());
+  DALI_TEST_CHECK(parser2.GetRoot());
+
+  CompareTrees( *parser.GetRoot(), *parser2.GetRoot() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index 9b6fa4f..46c7550 100644 (file)
@@ -722,6 +722,11 @@ bool JsonParserState::ParseJson(VectorChar& source)
       {
         if( '}' == currentChar )
         {
+          if(',' == lastCharacter)
+          {
+            return Error("Unexpected comma");
+          }
+
           if( !UpToParent() )
           {
             return false;
@@ -799,15 +804,22 @@ bool JsonParserState::ParseJson(VectorChar& source)
         }
         else if( '{' == currentChar )
         {
-          NewNode(name, TreeNode::OBJECT);
-          mState = STATE_OBJECT;
-          AdvanceSkipWhiteSpace(1);
+          if( '}' == lastCharacter )
+          {
+            return Error("Expected a comma");
+          }
+          else
+          {
+            NewNode(name, TreeNode::OBJECT);
+            mState = STATE_OBJECT;
+            AdvanceSkipWhiteSpace(1);
+          }
         }
         else if( '}' == currentChar )
         {
           if(',' == lastCharacter)
           {
-            return Error("Expected a value");
+            return Error("Expected another value");
           }
 
           if(mCurrent.GetType() != TreeNode::OBJECT)
index 51421ac..cc6d19b 100644 (file)
@@ -25,7 +25,7 @@ struct OptionalTypes
   typedef const T& ReturnType;
   static ReturnType Get(const ValueType& v) { return v; }
   static ValueType Set(const ReturnType v) { return v; }
-  static bool Ok(const ValueType v) { return true; }
+  static bool Ok(const ValueType& v) { return true; }
 };
 
 template <typename T>
@@ -67,26 +67,24 @@ public:
     return mOk == true ? &OptionalValue::this_type_does_not_support_comparisons : 0;
   }
 
-  template <typename OT>
-  bool operator!=( const OT& rhs )
-  {
-    this->this_type_does_not_support_comparisons();
-    return false;
-  }
-
-  template <typename OT>
-  bool operator==( const OT& rhs )
-  {
-    this->this_type_does_not_support_comparisons();
-    return false;
-  }
-
 private:
   bool mOk;
   ValueType mValue;
   void this_type_does_not_support_comparisons() const {}
-  // todo operator=() ? use OptionalTypes<T>::Ok(mValue)
 };
 
+template <typename T, typename U>
+bool operator==( const OptionalValue<T>& lhs, const OptionalValue<U>& rhs )
+{
+  lhs.this_type_does_not_support_comparisons();
+  return false;
+}
+
+template <typename T, typename U>
+bool operator!=( const OptionalValue<T>& lhs, const OptionalValue<U>& rhs )
+{
+  lhs.this_type_does_not_support_comparisons();
+  return false;
+}
 
 #endif // header
index c396f03..32f5f3e 100644 (file)
@@ -169,12 +169,12 @@ TreeNode* TreeNodeManipulator::Copy(const TreeNode& tree, int& numberNodes, int&
 
   if(tree.mName)
   {
-    numberChars += std::strlen(tree.mName);
+    numberChars += std::strlen(tree.mName) + 1;
   }
 
   if(TreeNode::STRING == tree.mType)
   {
-    numberChars += std::strlen(tree.mStringValue);
+    numberChars += std::strlen(tree.mStringValue) + 1;
   }
 
   ++numberNodes;