[ 
https://issues.apache.org/jira/browse/GROOVY-10710?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17579404#comment-17579404
 ] 

ASF GitHub Bot commented on GROOVY-10710:
-----------------------------------------

sonatype-lift[bot] commented on code in PR #1765:
URL: https://github.com/apache/groovy/pull/1765#discussion_r945299722


##########
src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java:
##########
@@ -562,6 +565,181 @@ public static List primitiveArrayToList(Object array) {
         return list;
     }
 
+    /**
+     * Allows conversion of arrays into an immutable List view
+     *
+     * @param array an array
+     * @return a List view of the array
+     */
+    public static List primitiveArrayToUnmodifiableList(Object array) {
+        return new ArrayToUnmodifiableListAdapter(array);
+    }
+
+    static class ArrayToUnmodifiableListAdapter implements List {
+        private Object delegate;
+
+        public ArrayToUnmodifiableListAdapter(Object delegate) {
+            Objects.requireNonNull(delegate);
+            this.delegate = delegate;
+        }
+
+        @Override
+        public int size() {
+            return Array.getLength(delegate);
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return size() == 0;
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            for (Object next : this) {
+                if (next.equals(o)) return true;
+            }
+            return false;
+        }
+
+        private class Itr implements Iterator {
+            private int idx = 0;
+
+            @Override
+            public boolean hasNext() {
+                return idx < size();
+            }
+
+            @Override
+            public Object next() {
+                return get(idx++);
+            }
+        }
+
+        @Override
+        public Iterator iterator() {
+            return new Itr();
+        }
+
+        @Override
+        public Object get(int index) {
+            Object item = Array.get(delegate, index);
+            if (item != null && item.getClass().isArray() && 
item.getClass().getComponentType().isPrimitive()) {
+                item = primitiveArrayToUnmodifiableList(item);
+            }
+            return item;
+        }
+
+        @Override
+        public int indexOf(Object o) {
+            int idx = 0;
+            boolean found = false;
+            while (!found && idx < size()) {
+                found = get(idx).equals(o);
+                if (!found) idx++;
+            }
+            return found ? idx : -1;
+        }
+
+        @Override
+        public int lastIndexOf(Object o) {
+            int idx = size() - 1;
+            boolean found = false;
+            while (!found && idx >= 0) {
+                found = get(idx).equals(o);

Review Comment:
   💬 2 similar findings have been found in this PR
   
   ---
   
   *NULL_DEREFERENCE:*  object returned by `get(idx)` could be null and is 
dereferenced at line 648.
   
   ---
   
   <details><summary><b>Expand here to view all instances of this 
finding</b></summary><br/>
   
   <div align="center">
   
   | **File Path** | **Line Number** |
   | -----------

> operator == is slow when comparing primitive arrays and lists
> -------------------------------------------------------------
>
>                 Key: GROOVY-10710
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10710
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>            Reporter: L
>            Priority: Major
>         Attachments: test1.groovy
>
>
> To perform checks like  a == b groovy runtime invokes method 
> DefaultTypeTransformation.compareEqual(Object left, Object right).
> This method is OK if both the left side and the right side are arrays. But it 
> is utterly broken if only one side of the comparison is an array:
>  # There are calls to primitiveArrayToList() *before* making sure whether 
> this is really necessary. This results in creation of most likely unnecessary 
> objects (lists). It is much better to perform more checks like 'whether the 
> other operand is a collection or array' and 'if so whether both left and 
> right operand have the same size'.
>  # The conversion with primitiveArrayToList() might also a break normal 
> equals() implementation which compareEqual(Object left, Object right) falls 
> back to if operands do not fall into the special cases. This is because the 
> original operands *are replaced* with results of primitiveArrayToList() and 
> equals() is invoked not on the original objects.
> This problem is present in the current 3.X, 4.X and 5.X versions of groovy.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to