Skip to content

Commit fb79e67

Browse files
authored
Limit transformation count while trying to annotate single node (#7588)
1 parent 05377f6 commit fb79e67

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

ydb/library/yql/ast/yql_expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2525,6 +2525,7 @@ struct TExprContext : private TNonCopyable {
25252525
ui64 StringsAllocationLimit = 100000000;
25262526
ui64 RepeatTransformLimit = 1000000;
25272527
ui64 RepeatTransformCounter = 0;
2528+
ui64 TypeAnnNodeRepeatLimit = 1000;
25282529
25292530
TGcNodeConfig GcConfig;
25302531

ydb/library/yql/core/type_ann/type_ann_expr.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class TTypeAnnotationTransformer : public TGraphTransformerBase {
180180
}
181181

182182
auto input = start;
183-
for (;;) {
183+
for (size_t transformCount = 0; true; ++transformCount) {
184184
TIssueScopeGuard issueScope(ctx.IssueManager, [this, input, &ctx]() -> TIssuePtr {
185185
TStringBuilder str;
186186
str << "At ";
@@ -258,6 +258,22 @@ class TTypeAnnotationTransformer : public TGraphTransformerBase {
258258
YQL_ENSURE(false, "Unknown state");
259259
}
260260

261+
if (transformCount >= ctx.TypeAnnNodeRepeatLimit) {
262+
TConvertToAstSettings settings;
263+
settings.AllowFreeArgs = true;
264+
auto ast = ConvertToAst(*input, ctx, settings);
265+
if (ast.Root) {
266+
TStringStream s;
267+
ast.Root->PrettyPrintTo(s, TAstPrintFlags::ShortQuote | TAstPrintFlags::AdaptArbitraryContent | TAstPrintFlags::PerLine);
268+
YQL_CLOG(INFO, Core) << "Too many transformations for node:\n" << s.Str();
269+
}
270+
ctx.AddError(TIssue(ctx.GetPosition(input->Pos()),
271+
TStringBuilder() << "YQL: Internal core error! Type annotation of node " << input->Content()
272+
<< " with type " << input->Type() << " takes too much iterations: "
273+
<< ctx.TypeAnnNodeRepeatLimit << ". You may set TypeAnnNodeRepeatLimit as flags for config provider."));
274+
return TStatus::Error;
275+
}
276+
261277
input->SetState(TExprNode::EState::TypePending);
262278
switch (input->Type()) {
263279
case TExprNode::Atom:

ydb/library/yql/providers/config/yql_config_provider.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,16 @@ namespace {
547547
return false;
548548
}
549549
}
550+
else if (name == "TypeAnnNodeRepeatLimit") {
551+
if (args.size() != 1) {
552+
ctx.AddError(TIssue(pos, TStringBuilder() << "Expected 1 argument, but got " << args.size()));
553+
return false;
554+
}
555+
if (!TryFromString(args[0], ctx.TypeAnnNodeRepeatLimit)) {
556+
ctx.AddError(TIssue(pos, TStringBuilder() << "Expected integer, but got: " << args[0]));
557+
return false;
558+
}
559+
}
550560
else if (name == "PureDataSource") {
551561
if (args.size() != 1) {
552562
ctx.AddError(TIssue(pos, TStringBuilder() << "Expected 1 argument, but got " << args.size()));

0 commit comments

Comments
 (0)