Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:25
erlang
0263-Fix-is_record-3-for-unreasonable-tuple-siz...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0263-Fix-is_record-3-for-unreasonable-tuple-sizes.patch of Package erlang
From a8eb23f7991fbdbf5e7fc524080ea9d3509b72c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Sun, 28 May 2023 07:25:40 +0200 Subject: [PATCH] Fix is_record/3 for unreasonable tuple sizes Calling `is_record/3` with a zero tuple size would crash the compiler. For example: foo(A) -> is_record(A, a, 0). Using the same kind of expression in a guard would generate incorrect code that could succeed. For example, given: bar(A) when is_record(A, a, 0) -> ok. the call `bar({a})` would succeed. The compiler would run out of memory or never finish compiling a call to `is_record/3` with a huge tuple size. Example: foobar(A) when is_record(A, a, 10000000) -> A. Closes #7298 Closes #7317 --- lib/compiler/test/record_SUITE.erl | 23 +++++++++++++++++++++++ lib/stdlib/src/erl_expand_records.erl | 16 ++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/lib/compiler/test/record_SUITE.erl b/lib/compiler/test/record_SUITE.erl index a098529380..92a5a8e05a 100644 --- a/lib/compiler/test/record_SUITE.erl +++ b/lib/compiler/test/record_SUITE.erl @@ -52,6 +52,7 @@ groups() -> init_per_suite(Config) -> + _ = id(Config), %Make return value unpredicatble. test_lib:recompile(?MODULE), Config. @@ -394,6 +395,28 @@ record_test_3(Config) when is_list(Config) -> true = is_record(Rec, Good, Size) orelse error, error = is_record(Rec, Bad, Size) orelse error, + %% GH-7298: Zero size. + TupleA = id({a}), + + false = is_record(TupleA, a, 0), + false = is_record(Bad, a, 0), + + ZeroF = fun(A) when is_record(A, a, 0) -> ok; + (_) -> error + end, + error = ZeroF(TupleA), + error = ZeroF(Bad), + + %% GH-7317: Huge tuple size used to take forever to compile. + false = is_record(TupleA, a, 10_000_000), + false = is_record(Bad, a, 10_000_000), + + HugeF = fun(A) when is_record(A, a, 10_000_000) -> ok; + (_) -> error + end, + error = HugeF(TupleA), + error = HugeF(Bad), + ok. record_access_in_guards(Config) when is_list(Config) -> diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl index 8cd78e597d..706b5fec6e 100644 --- a/lib/stdlib/src/erl_expand_records.erl +++ b/lib/stdlib/src/erl_expand_records.erl @@ -371,6 +371,12 @@ expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,is_record}}, expr({call,Anno,{tuple,_,[{atom,_,erlang},{atom,_,is_record}]}, [A,{atom,_,Name}]}, St) -> record_test(Anno, A, Name, St); +expr({call,Anno,{atom,_,is_record},[_,_,{integer,_,Sz}]}, St) + when is_integer(Sz), Sz =< 0 -> + {{atom,Anno,false},St}; +expr({call,Anno,{remote,_,{atom,_,erlang},{atom,_,is_record}}, + [_,_,{integer,_,Sz}]}, St) when is_integer(Sz), Sz =< 0 -> + {{atom,Anno,false},St}; expr({call,Anno,{atom,_AnnoA,record_info},[_,_]=As0}, St0) -> {As,St1} = expr_list(As0, St0), record_info_call(Anno, As, St1); @@ -919,11 +925,13 @@ opt_rec_vars_2({op,_,'orelse',Arg,{atom,_,fail}}, Rs) -> %% Since the second argument guarantees failure, %% it is safe to inspect the first argument. opt_rec_vars_2(Arg, Rs); -opt_rec_vars_2({call,_,{remote,_,{atom,_,erlang},{atom,_,is_record}}, - [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}, Rs) -> - orddict:store(V, {Tag,Sz}, Rs); +opt_rec_vars_2({call,Anno, + {remote,_,{atom,_,erlang},{atom,_,is_record}=IsRecord}, + Args}, Rs) -> + opt_rec_vars_2({call,Anno,IsRecord,Args}, Rs); opt_rec_vars_2({call,_,{atom,_,is_record}, - [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}, Rs) -> + [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}, Rs) + when is_integer(Sz), 0 < Sz, Sz < 100 -> orddict:store(V, {Tag,Sz}, Rs); opt_rec_vars_2(_, Rs) -> Rs. -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor