[vala/0.40] codegen: Improve array-dup-wrapper for empty arrays



commit 73ffc76f090c6fc300a3bc44952a0c5a391cd869
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sun May 24 19:25:41 2020 +0200

    codegen: Improve array-dup-wrapper for empty arrays
    
    Guard against negative lengths and consistently return NULL if allocated
    size would be 0.
    
    See https://gitlab.gnome.org/GNOME/vala/issues/999

 codegen/valaccodearraymodule.vala | 18 ++++++++++++++
 tests/Makefile.am                 |  1 +
 tests/arrays/empty-length-0.vala  | 52 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index ee614340f..0a2d614f4 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -509,12 +509,20 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                        gnew.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
 
                        CCodeExpression length_expr = new CCodeIdentifier ("length");
+                       CCodeBinaryOperator length_check_op;
                        // add extra item to have array NULL-terminated for all reference types
                        if (array_type.element_type.data_type != null && 
array_type.element_type.data_type.is_reference_type ()) {
                                length_expr = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, 
length_expr, new CCodeConstant ("1"));
+                               length_check_op = CCodeBinaryOperator.GREATER_THAN_OR_EQUAL;
+                       } else {
+                               length_check_op = CCodeBinaryOperator.GREATER_THAN;
                        }
                        gnew.add_argument (length_expr);
 
+                       // only attempt to dup if length >=/> 0, this deals with negative lengths and returns 
NULL
+                       var length_check = new CCodeBinaryExpression (length_check_op, new CCodeIdentifier 
("length"), new CCodeConstant ("0"));
+                       ccode.open_if (length_check);
+
                        ccode.add_declaration (get_ccode_name (array_type), cvardecl);
                        ccode.add_assignment (new CCodeIdentifier ("result"), gnew);
 
@@ -528,7 +536,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                        ccode.close ();
 
                        ccode.add_return (new CCodeIdentifier ("result"));
+
+                       ccode.close ();
+                       ccode.add_return (new CCodeIdentifier ("NULL"));
                } else {
+                       // only dup if length > 0, this deals with negative lengths and returns NULL
+                       var length_check = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, new 
CCodeIdentifier ("length"), new CCodeConstant ("0"));
+                       ccode.open_if (length_check);
+
                        var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
                        dup_call.add_argument (new CCodeIdentifier ("self"));
 
@@ -537,6 +552,9 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                        dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new 
CCodeIdentifier ("length"), sizeof_call));
 
                        ccode.add_return (dup_call);
+
+                       ccode.close ();
+                       ccode.add_return (new CCodeIdentifier ("NULL"));
                }
 
                // append to file
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f4badf3a7..b99bb6641 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -68,6 +68,7 @@ TESTS = \
        arrays/cast-silent-invalid.test \
        arrays/class-field-length-cname.vala \
        arrays/constant-element-access.vala \
+       arrays/empty-length-0.vala \
        arrays/expression-bracket.test \
        arrays/fixed-length-init0-not-allowed.vala \
        arrays/field-global-length-cname.vala \
diff --git a/tests/arrays/empty-length-0.vala b/tests/arrays/empty-length-0.vala
new file mode 100644
index 000000000..8d64f304a
--- /dev/null
+++ b/tests/arrays/empty-length-0.vala
@@ -0,0 +1,52 @@
+struct Manam {
+       string s;
+}
+
+string[] foo;
+int[] bar;
+Manam[] manam;
+
+string[] get_foo () {
+       return foo;
+}
+
+int[] get_bar () {
+       return bar;
+}
+
+Manam[] get_manam () {
+       return manam;
+}
+
+void main () {
+       {
+               foo = new string[0];
+               assert (foo != null);
+               assert (get_foo () != null);
+       }
+       {
+               foo = {};
+               assert (foo != null);
+               assert (get_foo () != null);
+       }
+       {
+               bar = new int[0];
+               //assert (bar != null);
+               assert (get_bar () == null);
+       }
+       {
+               bar = {};
+               //assert (bar != null);
+               assert (get_bar () == null);
+       }
+       {
+               manam = new Manam[0];
+               //assert (manam != null);
+               assert (get_manam () == null);
+       }
+       {
+               manam = {};
+               //assert (manam != null);
+               assert (get_manam () == null);
+       }
+}


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