@@ -168,7 +168,7 @@ namespace {
168
168
for (auto & arg: flag.GetArgs ()) {
169
169
args.push_back (arg);
170
170
}
171
- if (!ApplyFlag (pos, flag.GetName (), args, ctx)) {
171
+ if (!ApplyFlag (pos, flag.GetName (), args, ctx, 0 )) {
172
172
return false ;
173
173
}
174
174
}
@@ -260,15 +260,23 @@ 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 (!ApplyFlag (ctx.GetPosition (node->Child (2 )->Pos ()), command, args, ctx)) {
271
+ if (hasPendingEvaluations) {
272
+ if (!ValidateEvaluation (command, *node, ctx)) {
273
+ return {};
274
+ }
275
+
276
+ return res;
277
+ }
278
+
279
+ if (!ApplyFlag (ctx.GetPosition (node->Child (2 )->Pos ()), command, args, ctx, node->UniqueId ())) {
272
280
return {};
273
281
}
274
282
@@ -460,7 +468,30 @@ namespace {
460
468
return true ;
461
469
}
462
470
463
- bool ApplyFlag (const TPosition& pos, const TStringBuf name, const TVector<TStringBuf>& args, TExprContext& ctx) {
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 4 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 ()), node.UniqueId ()}).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
+
493
+ bool ApplyFlag (const TPosition& pos, const TStringBuf name, const TVector<TStringBuf>& args, TExprContext& ctx,
494
+ ui64 nodeUniqueId) {
464
495
if (!IsSettingAllowed (pos, name, ctx)) {
465
496
return false ;
466
497
}
@@ -474,15 +505,15 @@ namespace {
474
505
return false ;
475
506
}
476
507
} else if (name == " AddFileByUrl" ) {
477
- if (!AddFileByUrl (pos, args, ctx)) {
508
+ if (!AddFileByUrl (pos, args, ctx, nodeUniqueId )) {
478
509
return false ;
479
510
}
480
511
} else if (name == " SetFileOption" ) {
481
512
if (!SetFileOption (pos, args, ctx)) {
482
513
return false ;
483
514
}
484
515
} else if (name == " AddFolderByUrl" ) {
485
- if (!AddFolderByUrl (pos, args, ctx)) {
516
+ if (!AddFolderByUrl (pos, args, ctx, nodeUniqueId )) {
486
517
return false ;
487
518
}
488
519
} else if (name == " SetPackageVersion" ) {
@@ -985,12 +1016,13 @@ namespace {
985
1016
return true ;
986
1017
}
987
1018
988
- bool AddFileByUrl (const TPosition& pos, const TVector<TStringBuf>& args, TExprContext& ctx) {
1019
+ bool AddFileByUrl (const TPosition& pos, const TVector<TStringBuf>& args, TExprContext& ctx, ui64 nodeUniqueId ) {
989
1020
if (args.size () < 2 || args.size () > 3 ) {
990
1021
ctx.AddError (TIssue (pos, TStringBuilder () << " Expected 2 or 3 arguments, but got " << args.size ()));
991
1022
return false ;
992
1023
}
993
1024
1025
+ PendingEvaluationFiles.erase ({TString (args[0 ]),nodeUniqueId});
994
1026
TStringBuf token = args.size () == 3 ? args[2 ] : TStringBuf ();
995
1027
if (token) {
996
1028
if (auto cred = Types.Credentials ->FindCredential (token)) {
@@ -1104,12 +1136,13 @@ namespace {
1104
1136
return url;
1105
1137
}
1106
1138
1107
- bool AddFolderByUrl (const TPosition& pos, const TVector<TStringBuf>& args, TExprContext& ctx) {
1139
+ bool AddFolderByUrl (const TPosition& pos, const TVector<TStringBuf>& args, TExprContext& ctx, ui64 nodeUniqueId ) {
1108
1140
if (args.size () < 2 || args.size () > 3 ) {
1109
1141
ctx.AddError (TIssue (pos, TStringBuilder () << " Expected 2 or 3 arguments, but got " << args.size ()));
1110
1142
return false ;
1111
1143
}
1112
1144
1145
+ PendingEvaluationFiles.erase ({TString (args[0 ]),nodeUniqueId});
1113
1146
TStringBuf token = args.size () == 3 ? args[2 ] : TStringBuf ();
1114
1147
if (token) {
1115
1148
if (auto cred = Types.Credentials ->FindCredential (token)) {
@@ -1206,6 +1239,7 @@ namespace {
1206
1239
TString Username;
1207
1240
const TAllowSettingPolicy Policy;
1208
1241
TOperationStatistics Statistics;
1242
+ THashSet<std::pair<TString, ui64>> PendingEvaluationFiles;
1209
1243
};
1210
1244
}
1211
1245
0 commit comments