Il giorno mar, 26/09/2006 alle 11.53 -0400, Thomas Fitzsimmons ha
scritto:
> Hi,
>
> Mario Torre wrote:
> > 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.
>
> You're still using g_strdup_printf here:
ops... sorry, I was sleeping...
> Since you're not freeing _val, this is a memory leak.
>
> Tom
This should fix it, I have also remove declarations outside the while
loop, though I think gcc already optimize this.
Waiting for news... :)
Mario
--
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 27 Sep 2006 11:33:54 -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 27 Sep 2006 11:33:56 -0000
@@ -157,16 +157,19 @@
/*
* 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 */
const char *dir = NULL;
+ const char *_val = NULL;
+ const char *_val_unescaped = NULL;
+
GError *err = NULL;
GSList *entries = NULL;
GSList *tmp;
@@ -208,12 +211,18 @@
tmp = entries;
while (tmp != NULL)
{
- const char *_val = gconf_entry_get_key (tmp->data);
+ _val = gconf_entry_get_key (tmp->data);
_val = strrchr (_val, '/');
++_val;
+
+ _val_unescaped = gconf_unescape_key (_val, strlen (_val));
+
(*env)->CallBooleanMethod (env, jlist, jlist_add_id,
- (*env)->NewStringUTF (env, _val));
+ (*env)->NewStringUTF (env, _val_unescaped));
+
tmp = g_slist_next (tmp);
+
+ g_free ((gpointer) _val_unescaped);
}
/* clean up things */
@@ -226,14 +235,17 @@
/*
* 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;
+ const char *_val = NULL;
+ const char *_val_unescaped = NULL;
+
GError *err = NULL;
GSList *entries = NULL;
GSList *tmp;
@@ -274,12 +286,19 @@
tmp = entries;
while (tmp != NULL)
{
- const char *_val = tmp->data;
+ _val = tmp->data;
+
_val = strrchr (_val, '/');
++_val;
+
+ _val_unescaped = gconf_unescape_key (_val, strlen (_val));
+
(*env)->CallBooleanMethod (env, jlist, jlist_add_id,
- (*env)->NewStringUTF (env, _val));
+ (*env)->NewStringUTF (env, _val_unescaped));
+
tmp = g_slist_next (tmp);
+
+ g_free ((gpointer) _val_unescaped);
}
/* clean up things */
@@ -421,7 +440,7 @@
gdk_threads_leave ();
if (err != NULL)
{
- g_error_free (err);
+ g_error_free (err);
err = NULL;
result = JNI_FALSE;
}
@@ -534,6 +553,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 27 Sep 2006 11:33:54 -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 27 Sep 2006 11:33:56 -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.