@@ -36,7 +36,7 @@ func Clone(daemonURL, repoID, localPath string) error {
3636 // For each ref, fetch the commit and all reachable objects
3737 seen := make (map [string ]bool )
3838 for _ , ref := range repoInfo .Refs {
39- if err := fetchObjectRecursive (client , repoID , repo , ref .Hash , seen ); err != nil {
39+ if err := fetchObjectRecursive (client , repoID , repo , ref .Hash , seen , 0 ); err != nil {
4040 fmt .Fprintf (Stderr (), "warning: failed to fetch %s: %v\n " , ref .Hash , err )
4141 }
4242 }
@@ -55,7 +55,10 @@ func Clone(daemonURL, repoID, localPath string) error {
5555}
5656
5757// fetchObjectRecursive fetches an object and all its children
58- func fetchObjectRecursive (client * Client , repoID string , repo * git.Repository , hashStr string , seen map [string ]bool ) error {
58+ func fetchObjectRecursive (client * Client , repoID string , repo * git.Repository , hashStr string , seen map [string ]bool , depth int ) error {
59+ if depth > 1000 {
60+ return fmt .Errorf ("recursion depth limit exceeded" )
61+ }
5962 if seen [hashStr ] {
6063 return nil
6164 }
@@ -105,12 +108,12 @@ func fetchObjectRecursive(client *Client, repoID string, repo *git.Repository, h
105108 for _ , line := range strings .Split (contentStr , "\n " ) {
106109 if strings .HasPrefix (line , "tree " ) {
107110 treeHash := strings .TrimPrefix (line , "tree " )
108- if err := fetchObjectRecursive (client , repoID , repo , treeHash , seen ); err != nil {
111+ if err := fetchObjectRecursive (client , repoID , repo , treeHash , seen , depth + 1 ); err != nil {
109112 fmt .Fprintf (Stderr (), "warning: failed to fetch tree %s: %v\n " , treeHash , err )
110113 }
111114 } else if strings .HasPrefix (line , "parent " ) {
112115 parentHash := strings .TrimPrefix (line , "parent " )
113- if err := fetchObjectRecursive (client , repoID , repo , parentHash , seen ); err != nil {
116+ if err := fetchObjectRecursive (client , repoID , repo , parentHash , seen , depth + 1 ); err != nil {
114117 fmt .Fprintf (Stderr (), "warning: failed to fetch parent %s: %v\n " , parentHash , err )
115118 }
116119 }
@@ -131,7 +134,7 @@ func fetchObjectRecursive(client *Client, repoID string, repo *git.Repository, h
131134 break
132135 }
133136 entryHash := fmt .Sprintf ("%x" , content [nullIdx + 1 :nullIdx + 21 ])
134- if err := fetchObjectRecursive (client , repoID , repo , entryHash , seen ); err != nil {
137+ if err := fetchObjectRecursive (client , repoID , repo , entryHash , seen , depth + 1 ); err != nil {
135138 fmt .Fprintf (Stderr (), "warning: failed to fetch tree entry %s: %v\n " , entryHash , err )
136139 }
137140 i = nullIdx + 21
@@ -163,7 +166,7 @@ func Pull(repoPath, daemonURL, repoID string) error {
163166 // Fetch objects for new refs
164167 seen := make (map [string ]bool )
165168 for _ , ref := range repoInfo .Refs {
166- if err := fetchObjectRecursive (client , repoID , repo , ref .Hash , seen ); err != nil {
169+ if err := fetchObjectRecursive (client , repoID , repo , ref .Hash , seen , 0 ); err != nil {
167170 fmt .Fprintf (Stderr (), "warning: failed to fetch %s: %v\n " , ref .Hash , err )
168171 }
169172 }
0 commit comments