@@ -773,32 +773,23 @@ public XContentBuilder field(String name, Object value) throws IOException {
773773 }
774774
775775 public XContentBuilder array (String name , Object ... values ) throws IOException {
776- return field (name ).values (values );
776+ return field (name ).values (values , true );
777777 }
778778
779- XContentBuilder values (Object [] values ) throws IOException {
779+ private XContentBuilder values (Object [] values , boolean ensureNoSelfReferences ) throws IOException {
780780 if (values == null ) {
781781 return nullValue ();
782782 }
783783
784- // checks that the array of object does not contain references to itself because
785- // iterating over entries will cause a stackoverflow error
786- ensureNoSelfReferences (values );
787-
788- startArray ();
789- for (Object o : values ) {
790- value (o );
791- }
792- endArray ();
793- return this ;
784+ return value (Arrays .asList (values ), ensureNoSelfReferences );
794785 }
795786
796787 public XContentBuilder value (Object value ) throws IOException {
797- unknownValue (value );
788+ unknownValue (value , true );
798789 return this ;
799790 }
800791
801- private void unknownValue (Object value ) throws IOException {
792+ private void unknownValue (Object value , boolean ensureNoSelfReferences ) throws IOException {
802793 if (value == null ) {
803794 nullValue ();
804795 return ;
@@ -810,11 +801,11 @@ private void unknownValue(Object value) throws IOException {
810801 //Path implements Iterable<Path> and causes endless recursion and a StackOverFlow if treated as an Iterable here
811802 value ((Path ) value );
812803 } else if (value instanceof Map ) {
813- map ((Map ) value );
804+ map ((Map < String ,?> ) value , ensureNoSelfReferences );
814805 } else if (value instanceof Iterable ) {
815- value ((Iterable <?>) value );
806+ value ((Iterable <?>) value , ensureNoSelfReferences );
816807 } else if (value instanceof Object []) {
817- values ((Object []) value );
808+ values ((Object []) value , ensureNoSelfReferences );
818809 } else if (value instanceof Calendar ) {
819810 value ((Calendar ) value );
820811 } else if (value instanceof ReadableInstant ) {
@@ -863,18 +854,25 @@ public XContentBuilder field(String name, Map<String, Object> values) throws IOE
863854 }
864855
865856 public XContentBuilder map (Map <String , ?> values ) throws IOException {
857+ return map (values , true );
858+ }
859+
860+ private XContentBuilder map (Map <String , ?> values , boolean ensureNoSelfReferences ) throws IOException {
866861 if (values == null ) {
867862 return nullValue ();
868863 }
869864
870865 // checks that the map does not contain references to itself because
871866 // iterating over map entries will cause a stackoverflow error
872- ensureNoSelfReferences (values );
867+ if (ensureNoSelfReferences ) {
868+ ensureNoSelfReferences (values );
869+ }
873870
874871 startObject ();
875872 for (Map .Entry <String , ?> value : values .entrySet ()) {
876873 field (value .getKey ());
877- unknownValue (value .getValue ());
874+ // pass ensureNoSelfReferences=false as we already performed the check at a higher level
875+ unknownValue (value .getValue (), false );
878876 }
879877 endObject ();
880878 return this ;
@@ -884,7 +882,7 @@ public XContentBuilder field(String name, Iterable<?> values) throws IOException
884882 return field (name ).value (values );
885883 }
886884
887- private XContentBuilder value (Iterable <?> values ) throws IOException {
885+ private XContentBuilder value (Iterable <?> values , boolean ensureNoSelfReferences ) throws IOException {
888886 if (values == null ) {
889887 return nullValue ();
890888 }
@@ -895,11 +893,14 @@ private XContentBuilder value(Iterable<?> values) throws IOException {
895893 } else {
896894 // checks that the iterable does not contain references to itself because
897895 // iterating over entries will cause a stackoverflow error
898- ensureNoSelfReferences (values );
896+ if (ensureNoSelfReferences ) {
897+ ensureNoSelfReferences (values );
898+ }
899899
900900 startArray ();
901901 for (Object value : values ) {
902- unknownValue (value );
902+ // pass ensureNoSelfReferences=false as we already performed the check at a higher level
903+ unknownValue (value , false );
903904 }
904905 endArray ();
905906 }
@@ -1076,9 +1077,9 @@ private static void ensureNoSelfReferences(final Object value, final Set<Object>
10761077
10771078 Iterable <?> it ;
10781079 if (value instanceof Map ) {
1079- it = ((Map ) value ).values ();
1080+ it = ((Map <?,?> ) value ).values ();
10801081 } else if ((value instanceof Iterable ) && (value instanceof Path == false )) {
1081- it = (Iterable ) value ;
1082+ it = (Iterable <?> ) value ;
10821083 } else if (value instanceof Object []) {
10831084 it = Arrays .asList ((Object []) value );
10841085 } else {
0 commit comments