@@ -260,14 +260,22 @@ namespace {
260
260
for (size_t i = 3 ; i < node->ChildrenSize (); ++i) {
261
261
if (node->Child (i)->IsCallable (" EvaluateAtom" )) {
262
262
hasPendingEvaluations = true ;
263
- return res ;
263
+ break ;
264
264
}
265
265
if (!EnsureAtom (*node->Child (i), ctx)) {
266
266
return {};
267
267
}
268
268
args.push_back (node->Child (i)->Content ());
269
269
}
270
270
271
+ if (hasPendingEvaluations) {
272
+ if (!ValidateEvaluation (command, *node, ctx)) {
273
+ return {};
274
+ }
275
+
276
+ return res;
277
+ }
278
+
271
279
if (!ApplyFlag (ctx.GetPosition (node->Child (2 )->Pos ()), command, args, ctx)) {
272
280
return {};
273
281
}
@@ -460,6 +468,28 @@ namespace {
460
468
return true ;
461
469
}
462
470
471
+ bool ValidateEvaluation (const TStringBuf name, const TExprNode& node, TExprContext& ctx) {
472
+ if (name == " AddFileByUrl" || name == " AddFolderByUrl" ) {
473
+ if (node.ChildrenSize () < 4 ) {
474
+ ctx.AddError (TIssue (ctx.GetPosition (node.Pos ()), TStringBuilder () << " Expected at least 5 arguments, but got " << node.ChildrenSize ()));
475
+ return false ;
476
+ }
477
+
478
+ if (node.Child (3 )->IsCallable (" EvaluateAtom" )) {
479
+ return true ;
480
+ }
481
+
482
+ if (!PendingEvaluationFiles.insert (TString (node.Child (3 )->Content ())).second ) {
483
+ ctx.AddError (TIssue (ctx.GetPosition (node.Pos ()), TStringBuilder () << " Detected evaluation cycle for file: " << node.Child (3 )->Content ()));
484
+ return false ;
485
+ }
486
+
487
+ return true ;
488
+ } else {
489
+ return true ;
490
+ }
491
+ }
492
+
463
493
bool ApplyFlag (const TPosition& pos, const TStringBuf name, const TVector<TStringBuf>& args, TExprContext& ctx) {
464
494
if (!IsSettingAllowed (pos, name, ctx)) {
465
495
return false ;
@@ -991,6 +1021,7 @@ namespace {
991
1021
return false ;
992
1022
}
993
1023
1024
+ PendingEvaluationFiles.erase (TString (args[0 ]));
994
1025
TStringBuf token = args.size () == 3 ? args[2 ] : TStringBuf ();
995
1026
if (token) {
996
1027
if (auto cred = Types.Credentials ->FindCredential (token)) {
@@ -1110,6 +1141,7 @@ namespace {
1110
1141
return false ;
1111
1142
}
1112
1143
1144
+ PendingEvaluationFiles.erase (TString (args[0 ]));
1113
1145
TStringBuf token = args.size () == 3 ? args[2 ] : TStringBuf ();
1114
1146
if (token) {
1115
1147
if (auto cred = Types.Credentials ->FindCredential (token)) {
@@ -1206,6 +1238,7 @@ namespace {
1206
1238
TString Username;
1207
1239
const TAllowSettingPolicy Policy;
1208
1240
TOperationStatistics Statistics;
1241
+ THashSet<TString> PendingEvaluationFiles;
1209
1242
};
1210
1243
}
1211
1244
0 commit comments