You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by ne...@apache.org on 2021/11/10 11:33:40 UTC

[netbeans] branch delivery updated: Correct the parsing of String values in native image.

This is an automated email from the ASF dual-hosted git repository.

neilcsmith pushed a commit to branch delivery
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/delivery by this push:
     new dde532f  Correct the parsing of String values in native image.
     new 178570c  Merge pull request #3311 from entlicher/NI_StringEncoding_delivery
dde532f is described below

commit dde532fd3535485ee189ba7661311bbb1cb670eb
Author: Martin Entlicher <ma...@oracle.com>
AuthorDate: Tue Nov 9 10:54:11 2021 +0100

    Correct the parsing of String values in native image.
---
 .../debugger/displayer/JavaVariablesDisplayer.java | 65 +++++++++++++++++++---
 1 file changed, 58 insertions(+), 7 deletions(-)

diff --git a/java/java.nativeimage.debugger/src/org/netbeans/modules/java/nativeimage/debugger/displayer/JavaVariablesDisplayer.java b/java/java.nativeimage.debugger/src/org/netbeans/modules/java/nativeimage/debugger/displayer/JavaVariablesDisplayer.java
index 191e2a9..5f7035e 100644
--- a/java/java.nativeimage.debugger/src/org/netbeans/modules/java/nativeimage/debugger/displayer/JavaVariablesDisplayer.java
+++ b/java/java.nativeimage.debugger/src/org/netbeans/modules/java/nativeimage/debugger/displayer/JavaVariablesDisplayer.java
@@ -47,6 +47,7 @@ public final class JavaVariablesDisplayer implements VariableDisplayer {
     private static final String COMPRESSED_REF_REFIX = "_z_.";
     private static final String PUBLIC = "public";
     private static final String STRING_VALUE = "value";
+    private static final String STRING_CODER = "coder";
     private static final String HASH = "hash";
     private static final String UNSET = "<optimized out>";
 
@@ -240,6 +241,16 @@ public final class JavaVariablesDisplayer implements VariableDisplayer {
         return null;
     }
 
+    private String readArray(NIVariable lengthVariable, int offset, int itemSize) {
+        int length = Integer.parseInt(lengthVariable.getValue());
+        String expressionPath = lengthVariable.getExpressionPath();
+        if (expressionPath != null && !expressionPath.isEmpty()) {
+            String addressExpr = "&" + expressionPath;
+            return debugger.readMemory(addressExpr, 4 + offset, length * itemSize); // length has 4 bytes
+        }
+        return null;
+    }
+
     private static NIVariable[] getObjectChildren(NIVariable[] children, int from, int to) {
         for (int i = 0; i < children.length; i++) {
             if (HUB.equals(children[i].getName())) {
@@ -290,16 +301,37 @@ public final class JavaVariablesDisplayer implements VariableDisplayer {
         @Override
         public String getValue() {
             NIVariable pub = getVarsByName(var.getChildren()).get(PUBLIC);
-            Map<String, NIVariable> arrayInfo = getVarsByName(getVarsByName(pub.getChildren()).get(STRING_VALUE).getChildren());
+            Map<String, NIVariable> varChildren = getVarsByName(pub.getChildren());
+            Map<String, NIVariable> arrayInfo = getVarsByName(varChildren.get(STRING_VALUE).getChildren());
             arrayInfo = getVarsByName(arrayInfo.get(PUBLIC).getChildren());
             NIVariable arrayVariable = arrayInfo.get(ARRAY);
             NIVariable lengthVariable = arrayInfo.get(ARRAY_LENGTH);
-            String hexArray = readArray(lengthVariable, 2);
+            int length = Integer.parseInt(lengthVariable.getValue());
+            NIVariable coderVar = varChildren.get(STRING_CODER);
+            int coder = -1;
+            if (coderVar != null) {
+                String coderStr = coderVar.getValue();
+                int space = coderStr.indexOf(' ');
+                if (space > 0) {
+                    coderStr = coderStr.substring(0, space);
+                }
+                try {
+                    coder = Integer.parseInt(coderStr);
+                } catch (NumberFormatException ex) {
+                }
+            }
+            String hexArray = readArray(lengthVariable, coder == -1 ? 4 : 0, 2);
             if (hexArray != null) {
-                return parseUTF16(hexArray);
+                switch (coder) {
+                    case 0: // Compressed String on JDK 9+
+                        return parseLatin1(hexArray, length);
+                    case 1: // UTF-16 String on JDK 9+
+                        return parseUTF16(hexArray, length/2);
+                    default: // UTF-16 String on JDK 8
+                        return parseUTF16(hexArray, length);
+                }
             } else { // legacy code
                 String arrayExpression = getArrayExpression(arrayVariable);
-                int length = Integer.parseInt(lengthVariable.getValue());
                 char[] characters = new char[length];
                 try {
                     for (int i = 0; i < length; i++) {
@@ -313,10 +345,9 @@ public final class JavaVariablesDisplayer implements VariableDisplayer {
             }
         }
 
-        private String parseUTF16(String hexArray) {
-            CharsetDecoder cd = Charset.forName("utf-16").newDecoder();
+        private String parseUTF16(String hexArray, int length) {
+            CharsetDecoder cd = Charset.forName("utf-16").newDecoder(); // NOI18N
             ByteBuffer buffer = ByteBuffer.allocate(2);
-            int length = hexArray.length() / 4;
             char[] characters = new char[length];
             int ih = 0;
             for (int i = 0; i < length; i++) {
@@ -337,6 +368,26 @@ public final class JavaVariablesDisplayer implements VariableDisplayer {
             return new String(characters);
         }
 
+        private String parseLatin1(String hexArray, int length) {
+            CharsetDecoder cd = Charset.forName("latin1").newDecoder(); // NOI18N
+            ByteBuffer buffer = ByteBuffer.allocate(1);
+            char[] characters = new char[length];
+            int ih = 0;
+            for (int i = 0; i < length; i++) {
+                byte b = parseByte(hexArray, ih);
+                ih += 2;
+                buffer.rewind();
+                buffer.put(b);
+                buffer.rewind();
+                try {
+                    char c = cd.decode(buffer).get();
+                    characters[i] = c;
+                } catch (CharacterCodingException ex) {
+                }
+            }
+            return new String(characters);
+        }
+
         private byte parseByte(String hexArray, int offset) {
             String hex = new String(new char[] {hexArray.charAt(offset), hexArray.charAt(offset + 1)});
             return (byte) (Integer.parseInt(hex, 16) & 0xFF);

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists