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.