THRIFT-2471 Make cpp.ref annotation language agnostic
Client: compiler general
Patch: Dave Watson

This closes #113

commit 52b99af4ee1574253dcb77933d76a7ebb2d830df
 Author: Dave Watson <davejwatson@fb.com>
 Date: 2014-04-23T20:05:56Z

change cpp.ref to &

commit 3f9d31cc6140367529fd8f7b1b67056ec321786f
 Author: Dave Watson <davejwatson@fb.com>
 Date: 2014-04-23T21:50:29Z

Recursion depth limit

commit 61468e4534ce9e6a4f4f643bfd00542d13600d83
 Author: Dave Watson <davejwatson@fb.com>
 Date: 2014-04-25T19:59:18Z

shared_ptr for reference type
diff --git a/lib/cpp/src/thrift/protocol/TProtocol.h b/lib/cpp/src/thrift/protocol/TProtocol.h
index e72033a..e8ba429 100644
--- a/lib/cpp/src/thrift/protocol/TProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TProtocol.h
@@ -283,6 +283,8 @@
   return 0;
 }
 
+static const uint32_t DEFAULT_RECURSION_LIMIT = 64;
+
 /**
  * Abstract class for a thrift protocol driver. These are all the methods that
  * a protocol must implement. Essentially, there must be some way of reading
@@ -660,15 +662,28 @@
     return ptrans_;
   }
 
- protected:
-  TProtocol(boost::shared_ptr<TTransport> ptrans):
-    ptrans_(ptrans) {
+  void incrementRecursionDepth() {
+    if (recursion_limit_ < ++recursion_depth_) {
+      throw TProtocolException(TProtocolException::DEPTH_LIMIT);
+    }
   }
 
+  void decrementRecursionDepth() {
+    --recursion_depth_;
+  }
+
+ protected:
+  TProtocol(boost::shared_ptr<TTransport> ptrans)
+    : ptrans_(ptrans) 
+    , recursion_depth_(0)
+    , recursion_limit_(DEFAULT_RECURSION_LIMIT) {}
+
   boost::shared_ptr<TTransport> ptrans_;
 
  private:
   TProtocol() {}
+  uint32_t recursion_depth_;
+  uint32_t recursion_limit_;
 };
 
 /**
diff --git a/lib/cpp/src/thrift/protocol/TProtocolException.h b/lib/cpp/src/thrift/protocol/TProtocolException.h
index a03d3c8..4ddb81e 100644
--- a/lib/cpp/src/thrift/protocol/TProtocolException.h
+++ b/lib/cpp/src/thrift/protocol/TProtocolException.h
@@ -45,6 +45,7 @@
   , SIZE_LIMIT = 3
   , BAD_VERSION = 4
   , NOT_IMPLEMENTED = 5
+  , DEPTH_LIMIT = 6
   };
 
   TProtocolException() :
diff --git a/lib/cpp/test/RecursiveTest.cpp b/lib/cpp/test/RecursiveTest.cpp
index 00610c6..24c0f7c 100644
--- a/lib/cpp/test/RecursiveTest.cpp
+++ b/lib/cpp/test/RecursiveTest.cpp
@@ -44,7 +44,7 @@
   assert(tree == result);
 
   RecList l;
-  RecList* l2(new RecList);
+  boost::shared_ptr<RecList> l2(new RecList);
   l.nextitem = l2;
 
   l.write(prot.get());
@@ -55,7 +55,7 @@
   assert(resultlist.nextitem->nextitem == NULL);
 
   CoRec c;
-  CoRec2* r(new CoRec2);
+  boost::shared_ptr<CoRec2> r(new CoRec2);
   c.other = r;
 
   c.write(prot.get());
@@ -64,4 +64,12 @@
   assert(c.other != NULL);
   assert(c.other->other.other == NULL);
 
+  boost::shared_ptr<RecList> depthLimit(new RecList);
+  depthLimit->nextitem = depthLimit;
+  try {
+    depthLimit->write(prot.get());
+    assert(false);
+  } catch (const apache::thrift::protocol::TProtocolException& e) {
+  }
+
 }