[vala/0.36] vala: Break possible endless loop in SymbolResolver.get_type_for_struct()



commit 2f6febbba3051cb9df862f823569d641e35eca1c
Author: Florian Brosch <flo brosch gmail com>
Date:   Wed Sep 10 13:07:11 2014 +0200

    vala: Break possible endless loop in SymbolResolver.get_type_for_struct()
    
    Required to deal with invalid code containing base struct cycles.
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/444

 vala/valasymbolresolver.vala | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
---
diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala
index db31aa0ce..d24cc06bf 100644
--- a/vala/valasymbolresolver.vala
+++ b/vala/valasymbolresolver.vala
@@ -88,7 +88,7 @@ public class Vala.SymbolResolver : CodeVisitor {
                        if (base_type != null) {
                                if (base_type.is_subtype_of (st)) {
                                        st.error = true;
-                                       Report.error (base_type.source_reference, "Base struct cycle (`%s' 
and `%s')".printf (st.get_full_name (), base_type.get_full_name ()));
+                                       Report.error (st.source_reference, "Base struct cycle (`%s' and 
`%s')".printf (st.get_full_name (), base_type.get_full_name ()));
                                        return;
                                }
                        }
@@ -263,10 +263,33 @@ public class Vala.SymbolResolver : CodeVisitor {
                }
        }
 
+       bool has_base_struct_cycle (Struct st, Struct loop_st) {
+               if (!(st.base_type is UnresolvedType)) {
+                       return false;
+               }
+
+               var sym = resolve_symbol (((UnresolvedType) st.base_type).unresolved_symbol);
+               unowned Struct? base_struct = sym as Struct;
+               if (base_struct == null) {
+                       return false;
+               }
+
+               if (base_struct == loop_st) {
+                       return true;
+               }
+
+               return has_base_struct_cycle (base_struct, loop_st);
+       }
+
        DataType get_type_for_struct (Struct st, Struct base_struct) {
                if (st.base_type != null) {
                        // make sure that base type is resolved
 
+                       if (has_base_struct_cycle (st, st)) {
+                               // recursive declaration in base type
+                               return new StructValueType (st);
+                       }
+
                        if (current_scope == st.scope) {
                                // recursive declaration in generic base type
                                return new StructValueType (st);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]