Il giorno dom, 24/09/2006 alle 21.09 +0200, Mario Torre ha scritto:

Thomas Fitzsimmons kindly reviewed my patch on #classpath.

As a result, this a little update (hope I'm not missing something,
please let me know in this case).

I have removed the call to g_strdup_printf completely, I assume that it
is safe, as gconf_escape_key already returns a newly allocate and
stripped string.

Mario

> 2006-09-24  Mario Torre  <[EMAIL PROTECTED]>
> 
>       * scripts/check_jni_methods.sh: added two new methods in the
>       ignore list:
>       Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1escape_1key
>       and
>       Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1unescape_1key
>       * native/jni/gconf-peer/GConfNativePeer.c:
> 
> (Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1all_1keys):
>       refacored method name, renamed from
> 
> Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1keys.
>       Added code to unescape escaped GConf key names.
> 
> (Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1all_1nodes):
>       refacored method name, renamed from
> 
> Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1nodes.
>       Added code to unescape escaped GConf key names.
>       (Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1escape_1key):
>       new function.
>       (Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1unescape_1key):
>       new function.
>       * gnu/java/util/prefs/gconf/GConfNativePeer.java: removed
>       version javadoc tag.
>       (escapeString): new method.
>       (unescapeString): likewise.
>       (gconf_escape_key): new native method.
>       (gconf_unescape_key): likewise.
>       (gconf_client_suggest_sync): update native method signature, now
>       explicity throws BackingStoreException.
>       (gconf_client_all_nodes): update native method signature, now
>       explicity throws BackingStoreException. Refactored method name,
>       renamed from gconf_client_gconf_client_all_nodes.
>       (gconf_client_all_keys): update native method signature, now
>       explicity throws BackingStoreException. Refactored method name,
>       renamed from gconf_client_gconf_client_all_keys.
>       (getKeys): refactored to use the new method name
>       gconf_client_all_keys.
>       (getChildrenNodes): refactored to use the new method name
>       gconf_client_all_nodes.
>       * gnu/java/util/prefs/GConfBasedPreferences.java: removed
>       version javadoc tag.
>       (GConfBasedPreferences): Added code to escape node names from
>       invalid characters so that GConf now accept invalid node names.
>       (GConfBasedPreferences): Moved code to register the current
>       node to the list of nodes watched by GConf outside the constructor.
>       (childSpi): Added code to register the current node to the
>       list of nodes watched by GConf.
>       (getGConfKey): Added code to escape key names from
>       invalid characters so that GConf now accept invalid key names.
> 
-- 
Lima Software, SO.PR.IND. s.r.l.
http://www.limasoftware.net/
pgp key: http://subkeys.pgp.net/

Proud GNU Classpath developer: http://www.classpath.org/
Read About us at: http://planet.classpath.org

Please, support open standards:
http://opendocumentfellowship.org/petition/
http://www.nosoftwarepatents.com/
### Eclipse Workspace Patch 1.0
#P classpath
Index: gnu/java/util/prefs/gconf/GConfNativePeer.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java,v
retrieving revision 1.2
diff -u -r1.2 GConfNativePeer.java
--- gnu/java/util/prefs/gconf/GConfNativePeer.java	8 Jul 2006 22:28:16 -0000	1.2
+++ gnu/java/util/prefs/gconf/GConfNativePeer.java	26 Sep 2006 09:43:11 -0000
@@ -45,7 +45,6 @@
  * Native peer for GConf based preference backend.
  * 
  * @author Mario Torre <[EMAIL PROTECTED]>
- * @version 1.0.1
  */
 public final class GConfNativePeer
 {
@@ -150,7 +149,7 @@
    */
   public List getKeys(String node) throws BackingStoreException
   {
-    return gconf_client_gconf_client_all_keys(node);
+    return gconf_client_all_keys(node);
   }
 
   /**
@@ -162,10 +161,26 @@
    */
   public List getChildrenNodes(String node) throws BackingStoreException
   {
-    return gconf_client_gconf_client_all_nodes(node);
+    return gconf_client_all_nodes(node);
   }
 
   /**
+   * Escape the given string so the it is a valid GConf name.
+   */
+  public static String escapeString(String plain)
+  {
+    return gconf_escape_key(plain);
+  }
+  
+  /**
+   * Unescape a string escaped with [EMAIL PROTECTED] #escapeString}.
+   */
+  public static String unescapeString(String escaped)
+  {
+    return gconf_unescape_key(escaped);
+  }
+  
+  /**
    * Suggest to the backend GConf daemon to synch with the database.
    */
   public void suggestSync() throws BackingStoreException
@@ -270,8 +285,9 @@
    * Suggest to the GConf native peer a sync with the database.
    *
    */
-  native static final protected void gconf_client_suggest_sync();
-
+  native static final protected void gconf_client_suggest_sync()
+    throws BackingStoreException;
+  
   /**
    * Returns a list of all nodes under the given node.
    * 
@@ -279,8 +295,9 @@
    * @return A list of nodes under the given source node.
    */
   native
-  static final protected List gconf_client_gconf_client_all_nodes(String node);
-
+  static final protected List gconf_client_all_nodes(String node)
+    throws BackingStoreException;
+  
   /**
    * Returns a list of all keys stored in the given node.
    * 
@@ -288,8 +305,28 @@
    * @return A list of all keys stored in the given node.
    */
   native
-  static final protected List gconf_client_gconf_client_all_keys(String node);
+  static final protected List gconf_client_all_keys(String node)
+    throws BackingStoreException;
 
+  /**
+   * Escape the input String so that it's a valid element for GConf.
+   * 
+   * @param plain the String to escape.
+   * @return An escaped String for use with GConf.
+   */
+  native
+  static final protected String gconf_escape_key(String plain);
+  
+  /**
+   * Converts a string escaped with gconf_escape_key back into its
+   * original form.
+   * 
+   * @param escaped key as returned by gconf_escape_key 
+   * @return An unescaped key.
+   */
+  native
+  static final protected String gconf_unescape_key(String escaped);
+  
   static
     {
       System.loadLibrary("gconfpeer");
Index: native/jni/gconf-peer/GConfNativePeer.c
===================================================================
RCS file: /sources/classpath/classpath/native/jni/gconf-peer/GConfNativePeer.c,v
retrieving revision 1.7
diff -u -r1.7 GConfNativePeer.c
--- native/jni/gconf-peer/GConfNativePeer.c	4 Aug 2006 10:14:15 -0000	1.7
+++ native/jni/gconf-peer/GConfNativePeer.c	26 Sep 2006 09:43:12 -0000
@@ -157,11 +157,11 @@
 
 /*
  * Class:     gnu_java_util_prefs_gconf_GConfNativePeer
- * Method:    gconf_client_gconf_client_all_keys
+ * Method:    gconf_client_all_keys
  * Signature: (Ljava/lang/String;)Ljava/util/List;
  */
 JNIEXPORT jobject JNICALL
-Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1keys
+Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1all_1keys
   (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
 {
   /* TODO: check all the calls to gdk_threads_enter/leave */
@@ -211,6 +211,7 @@
       const char *_val = gconf_entry_get_key (tmp->data);
       _val = strrchr (_val, '/');
       ++_val;
+      _val = g_strdup_printf("%s", gconf_unescape_key(_val, strlen(_val)));
       (*env)->CallBooleanMethod (env, jlist, jlist_add_id,
 				 (*env)->NewStringUTF (env, _val));
       tmp = g_slist_next (tmp);
@@ -226,11 +227,11 @@
 
 /*
  * Class:     gnu_java_util_prefs_gconf_GConfNativePeer
- * Method:    gconf_client_gconf_client_all_nodes
+ * Method:    gconf_client_all_nodes
  * Signature: (Ljava/lang/String;)Ljava/util/List;
  */
 JNIEXPORT jobject JNICALL
-Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1gconf_1client_1all_1nodes
+Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1client_1all_1nodes
   (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring node)
 {
   const char *dir = NULL;
@@ -277,6 +278,7 @@
       const char *_val = tmp->data;
       _val = strrchr (_val, '/');
       ++_val;
+      _val = g_strdup_printf("%s", gconf_unescape_key(_val, strlen(_val)));
       (*env)->CallBooleanMethod (env, jlist, jlist_add_id,
 				 (*env)->NewStringUTF (env, _val));
       tmp = g_slist_next (tmp);
@@ -534,6 +536,74 @@
   reference_count--;
 }
 
+/*
+ * Class:     gnu_java_util_prefs_gconf_GConfNativePeer
+ * Method:    Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1escape_1key
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jstring
+JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1escape_1key
+  (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring plain)
+{
+  const char *escaped = NULL;
+  const char *_plain = NULL;
+  jstring result = NULL;
+  
+  _plain = JCL_jstring_to_cstring (env, plain);
+  if (_plain == NULL)
+    {
+      return NULL;
+    }
+
+  gdk_threads_enter ();
+  escaped = gconf_escape_key (_plain, strlen(_plain));
+  gdk_threads_leave ();
+  
+  JCL_free_cstring (env, plain, _plain);
+  /* check for NULL, if so prevent string creation */
+  if (escaped != NULL)
+    {
+      result = (*env)->NewStringUTF (env, escaped);
+      g_free ((gpointer) escaped);
+    }
+  
+  return result;
+}
+
+/*
+ * Class:     gnu_java_util_prefs_gconf_GConfNativePeer
+ * Method:    Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1unescape_1key
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jstring
+JNICALL Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1unescape_1key
+  (JNIEnv *env, jclass clazz __attribute__ ((unused)), jstring escaped)
+{
+  const char *plain = NULL;
+  const char *_escaped = NULL;
+  jstring result = NULL;
+  
+  _escaped = JCL_jstring_to_cstring (env, escaped);
+  if (_escaped == NULL)
+    {
+      return NULL;
+    }
+
+  gdk_threads_enter ();
+  plain = gconf_unescape_key (_escaped, strlen(_escaped));
+  gdk_threads_leave ();
+  
+  JCL_free_cstring (env, escaped, _escaped);
+  /* check for NULL, if so prevent string creation */
+  if (plain != NULL)
+    {
+      result = (*env)->NewStringUTF (env, plain);
+      g_free ((gpointer) plain);
+    }
+  
+  return result;
+}
+
 /* ***** END: NATIVE FUNCTIONS ***** */
 
 /* ***** PRIVATE FUNCTIONS IMPLEMENTATION ***** */
Index: gnu/java/util/prefs/GConfBasedPreferences.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/util/prefs/GConfBasedPreferences.java,v
retrieving revision 1.2
diff -u -r1.2 GConfBasedPreferences.java
--- gnu/java/util/prefs/GConfBasedPreferences.java	8 Jul 2006 22:28:17 -0000	1.2
+++ gnu/java/util/prefs/GConfBasedPreferences.java	26 Sep 2006 09:43:11 -0000
@@ -72,7 +72,6 @@
  * <br />
  * 
  * @author Mario Torre <[EMAIL PROTECTED]>
- * @version 1.0.1
  */
 public class GConfBasedPreferences
     extends AbstractPreferences
@@ -136,12 +135,20 @@
         absolutePath = absolutePath.substring(0, absolutePath.length() - 1);
       }
 
+    // strip invalid characters
+    // please, note that all names are unescaped into the native peer
+    int index = absolutePath.lastIndexOf('/');
+    if (index > -1)
+      {
+        absolutePath = absolutePath.substring(0, index + 1);
+        absolutePath = absolutePath + GConfNativePeer.escapeString(name);
+      }
+    
     this.node = this.getRealRoot(isUser) + absolutePath;
 
     boolean nodeExist = backend.nodeExist(this.node);
 
     this.newNode = !nodeExist;
-    backend.startWatchingNode(this.node);
   }
 
   /**
@@ -156,7 +163,15 @@
     // we don't check anything here, if the node is a new node this will be
     // detected in the constructor, so we simply return a new reference to
     // the requested node.
-    return new GConfBasedPreferences(this, name, this.isUser);
+    
+    GConfBasedPreferences preferenceNode
+      = new GConfBasedPreferences(this, name, this.isUser);
+    
+    // register the node for to GConf so that it can listen
+    // events outside the scope of the application
+    backend.startWatchingNode(this.node);
+    
+    return preferenceNode;
   }
 
   /**
@@ -365,6 +380,10 @@
   {
     String nodeName = "";
     
+    // strip key
+    // please, note that all names are unescaped into the native peer
+    key = GConfNativePeer.escapeString(key);
+    
     if (this.node.endsWith("/"))
       {
         nodeName = this.node + key;
@@ -373,7 +392,7 @@
       {
         nodeName = this.node + "/" + key;
       }
-
+    
     return nodeName;
   }
 
Index: scripts/check_jni_methods.sh
===================================================================
RCS file: /sources/classpath/classpath/scripts/check_jni_methods.sh,v
retrieving revision 1.13
diff -u -r1.13 check_jni_methods.sh
--- scripts/check_jni_methods.sh	18 Aug 2006 19:56:30 -0000	1.13
+++ scripts/check_jni_methods.sh	26 Sep 2006 09:43:12 -0000
@@ -38,6 +38,8 @@
 -Java_gnu_java_util_prefs_gconf_GConfNativePeer_finalize_1class
 -Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1id_1cache
 -Java_gnu_java_util_prefs_gconf_GConfNativePeer_init_1class
+-Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1escape_1key
+-Java_gnu_java_util_prefs_gconf_GConfNativePeer_gconf_1unescape_1key
 EOF
 
 # Compare again silently.

Reply via email to