From b081cf077eea54f4686a9e8b8d05d9ac12a2eee2 Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Fri, 10 Nov 2023 18:17:02 -0700 Subject: [PATCH] LibIDL: Verify inner type of nullable type is valid --- Userland/Libraries/LibIDL/IDLParser.cpp | 32 ++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibIDL/IDLParser.cpp b/Userland/Libraries/LibIDL/IDLParser.cpp index 7341d045c8..6e19273d08 100644 --- a/Userland/Libraries/LibIDL/IDLParser.cpp +++ b/Userland/Libraries/LibIDL/IDLParser.cpp @@ -187,8 +187,16 @@ NonnullRefPtr Parser::parse_type() assert_specific(')'); bool nullable = lexer.consume_specific('?'); + auto type = adopt_ref(*new UnionType("", nullable, move(union_member_types))); - return adopt_ref(*new UnionType("", nullable, move(union_member_types))); + if (nullable) { + if (type->number_of_nullable_member_types() > 0) + report_parsing_error("nullable union type cannot contain another nullable type"sv, filename, input, lexer.tell()); + + // FIXME: A nullable union type cannot include a dictionary type as one of its flattened member types. + } + + return type; } bool unsigned_ = lexer.consume_specific("unsigned"); @@ -224,6 +232,28 @@ NonnullRefPtr Parser::parse_type() builder.append("unsigned "sv); builder.append(name); + if (nullable) { + // https://webidl.spec.whatwg.org/#dfn-nullable-type + // The inner type must not be: + // - any, + if (name == "any"sv) + report_parsing_error("'any' cannot be nullable"sv, filename, input, lexer.tell()); + + // - a promise type, + if (name == "Promise"sv) + report_parsing_error("'Promise' cannot be nullable"sv, filename, input, lexer.tell()); + + // - an observable array type, + if (name == "ObservableArray") + report_parsing_error("'ObservableArray' cannot be nullable"sv, filename, input, lexer.tell()); + + // - another nullable type, or + + // - a union type that itself includes a nullable type or has a dictionary type as one of its flattened + // member types + // Note: This case is handled above + } + if (is_parameterized_type) return adopt_ref(*new ParameterizedType(builder.to_deprecated_string(), nullable, move(parameters)));