Re: Bug in Kannel WML Compiler??

Jörg Pommnitz <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hi List,
attached is a patch to the Kannel WML compiler that fixes the
problem described in my original post.

With this patch applied, the following test WML document:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="c1" title="A WMLC Testcase">
    <onevent type="onenterforward">
	<refresh>
		<setvar name="XY" value="This is the content"/>
	</refresh>
    </onevent>
    <p align="left">
	<a href="http://wap.url.mobile/path?XY=$XY">$XY</a><br/>
	<a href="http://wap.url.mobile/path?XY=$(XY)">$(XY)</a><br/>
	<a
href="http://wap.url.mobile/path?XY=$(XY:escape)">$(XY:escape)</a><br/>
	<a
href="http://wap.url.mobile/path?XY=$(XY:noesc)">$(XY:noesc)</a><br/>
	<a
href="http://wap.url.mobile/path?XY=$(XY:unesc)">$(XY:unesc)</a><br/>
    </p>
</card>
</wml>

results in the following (decompiled) binary:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="c1" title="A WMLC Testcase" >
<onevent type="onenterforward" >
<refresh>
<setvar name="XY" value="This is the content" />
</refresh>
</onevent>
<p align="left" >
<a href="http://wap.url.mobile/path?XY=$(XY:escape)" >$(XY:noesc)</a>
<br />
<a href="http://wap.url.mobile/path?XY=$(XY:escape)" >$(XY:noesc)</a>
<br />
<a href="http://wap.url.mobile/path?XY=$(XY:escape)" >$(XY:escape)</a>
<br />
<a href="http://wap.url.mobile/path?XY=$(XY:noesc)" >$(XY:noesc)</a>
<br />
<a href="http://wap.url.mobile/path?XY=$(XY:unesc)" >$(XY:unesc)</a>
<br />
</p>
</card>
</wml>

As you can see, the compiler now chooses the right conversion for the 
context, when no conversion is supplied.

Regards
  Jörg

-----Ursprüngliche Nachricht-----
Von: Jörg Pommnitz 
Gesendet: Montag, 29. März 2004 16:21
An: Kannel-Devel (E-Mail)
Betreff: Bug in Kannel WML Compiler??


Hello all,
I suspect that there is a small bug in the Kannel WML compiler.
The bug is related to variable substitution as specified in 
http://www.openmobilealliance.org/tech/affiliates/wap/wap-191-wml-20000219-a
.pdf
. Section 10.3.1 Variable Substitution says:

"If no conversion is specified, the variable is substituted using the 
conversion format appropriate for the context. All attributes defined 
as %HREF; default to escape conversion, elsewhere no conversion is 
done. Specifying the noesc conversion disables context sensitive 
escaping of a variable."

The WML binary standard does not provide a token for a variable
substitution without conversion (the defined tokens are EXT_I_0
..EXT_I_2, EXT_T_0..EXT_T_2), that's why the WML compiler has to choose
the correct one. Currently the WML compiler unconditionaly uses
the "noesc" conversion for all contexts, even in the href attribute:
http://www.kannel.org/cgi-bin/lxr/source/gateway/gw/wml_compiler.c#L1107

Unfortunately the function "check_variable_syntax" does not even
know the context. Any suggestions?

Regards
  Jörg
compiler.diff (application/octet-stream, 5.8 KB)
--- wml_compiler.c.~1.114.~	2004-02-16 19:55:22.000000000 +0100
+++ wml_compiler.c	2004-03-29 17:03:40.000000000 +0200
@@ -236,11 +236,11 @@
 static int parse_node(xmlNodePtr node, wml_binary_t **wbxml);
 static int parse_element(xmlNodePtr node, wml_binary_t **wbxml);
 static int parse_attribute(xmlAttrPtr attr, wml_binary_t **wbxml);
-static int parse_attr_value(Octstr *attr_value, List *tokens, 
-			    wml_binary_t **wbxml, int charset);
+static int parse_attr_value(Octstr *attr_value, List *tokens,
+			    wml_binary_t **wbxml, int charset, var_esc_t default_esc);
 static int parse_text(xmlNodePtr node, wml_binary_t **wbxml);
 static int parse_cdata(xmlNodePtr node, wml_binary_t **wbxml);
-static int parse_st_octet_string(Octstr *ostr, int cdata, wml_binary_t **wbxml);
+static int parse_st_octet_string(Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml);
 static void parse_st_end(wml_binary_t **wbxml);
 static void parse_entities(Octstr *wml_source);
 
@@ -248,10 +248,11 @@
  * Variable functions. These functions are used to find and parse variables.
  */
 
-static int parse_variable(Octstr *text, int start, Octstr **output, 
+static int parse_variable(Octstr *text, int start, var_esc_t default_esc, Octstr **output, 
 			  wml_binary_t **wbxml);
 static Octstr *get_variable(Octstr *text, int start);
-static var_esc_t check_variable_syntax(Octstr *variable);
+static var_esc_t check_variable_syntax(Octstr *variable, var_esc_t default_esc);
+
 
 /*
  * wml_binary-functions. These are used to create, destroy and modify
@@ -775,6 +776,10 @@
     }
 
     if (status >= 0) {
+	var_esc_t default_esc;
+
+	default_esc = (octstr_str_compare (name, "href") == 0) ? ESC : NOESC;
+
 	/* The rest of the attribute is coded as a inline string. */
 	if (pattern != NULL && 
 	    coded_length < (int) octstr_len(pattern)) {
@@ -786,10 +791,10 @@
 
 	    if (check_if_url(wbxml_hex))
 		status = parse_attr_value(p, wml_URL_values_list,
-					  wbxml, attr->doc->charset);
+					  wbxml, attr->doc->charset, default_esc);
 	    else
 		status = parse_attr_value(p, wml_attr_values_list,
-					  wbxml, attr->doc->charset);
+					  wbxml, attr->doc->charset, default_esc);
 	    if (status != 0)
 		error(0, 
 		      "WML compiler: could not output attribute "
@@ -814,7 +819,7 @@
  */
 
 static int parse_attr_value(Octstr *attr_value, List *tokens,
-			    wml_binary_t **wbxml, int charset)
+			    wml_binary_t **wbxml, int charset, var_esc_t default_esc)
 {
     int i, pos, wbxml_hex;
     wml_hash_t *temp = NULL;
@@ -849,7 +854,7 @@
     /* A fast patch to allow reserved names to be variable names. May produce 
        a little longer binary at some points. --tuo */
     if (octstr_search_char(attr_value, '$', 0) >= 0) {
-	if (parse_st_octet_string(attr_value, 0, wbxml) != 0)
+	if (parse_st_octet_string(attr_value, 0, default_esc, wbxml) != 0)
 	    return -1;
     } else {
 
@@ -872,7 +877,7 @@
 		gw_assert(pos <= octstr_len(attr_value));
 	
 		cut_text = octstr_copy(attr_value, 0, pos);
-		if (parse_st_octet_string(cut_text, 0, wbxml) != 0)
+		if (parse_st_octet_string(cut_text, 0, default_esc, wbxml) != 0)
 		    return -1;
 		octstr_destroy(cut_text);
 	    
@@ -891,9 +896,9 @@
 
 	if ((int) octstr_len(attr_value) > 0) {
 	    if (i < list_len(tokens))
-		parse_attr_value(attr_value, tokens, wbxml, charset);
+		parse_attr_value(attr_value, tokens, wbxml, charset, default_esc);
 	    else
-		if (parse_st_octet_string(attr_value, 0, wbxml) != 0)
+		if (parse_st_octet_string(attr_value, 0, default_esc, wbxml) != 0)
 		    return -1;
 	}
     }
@@ -949,7 +954,7 @@
     if (octstr_len(temp) == 0)
         ret = 0;
     else 
-        ret = parse_st_octet_string(temp, 0, wbxml);
+        ret = parse_st_octet_string(temp, 0, NOESC, wbxml);
 
     /* Memory cleanup. */
     octstr_destroy(temp);
@@ -972,7 +977,7 @@
 
     temp = create_octstr_from_node(node);
 
-    parse_st_octet_string(temp, 1, wbxml);
+    parse_st_octet_string(temp, 1, NOESC, wbxml);
     
     /* Memory cleanup. */
     octstr_destroy(temp);
@@ -993,7 +998,7 @@
  * Parsed variable is returned as an octet string in Octstr **output.
  */
 
-static int parse_variable(Octstr *text, int start, Octstr **output, 
+static int parse_variable(Octstr *text, int start, var_esc_t default_esc, Octstr **output, 
 			  wml_binary_t **wbxml)
 {
     var_esc_t esc;
@@ -1016,7 +1021,7 @@
 	else
 	    ret = octstr_len(variable) + 1;
 
-	if ((esc = check_variable_syntax(variable)) != FAILED)
+	if ((esc = check_variable_syntax(variable, default_esc)) != FAILED)
 	    output_variable(variable, output, esc, wbxml);
 	else
 	    octstr_destroy(variable);
@@ -1074,7 +1079,7 @@
  * escape mode it has. Octstr *variable contains the variable string.
  */
 
-static var_esc_t check_variable_syntax(Octstr *variable)
+static var_esc_t check_variable_syntax(Octstr *variable, var_esc_t default_esc)
 {
     Octstr *escape;
     char ch;
@@ -1104,7 +1109,7 @@
 	}
 	octstr_destroy(escape);
     } else
-	ret = NOESC;
+	ret = default_esc;
 
     ch = octstr_get_char(variable, 0);
     if (!(isalpha((int)ch)) && ch != '_') {
@@ -1131,7 +1136,7 @@
  * not. Returns 0 for success, -1 for error.
  */
 
-static int parse_st_octet_string(Octstr *ostr, int cdata, wml_binary_t **wbxml)
+static int parse_st_octet_string(Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml)
 {
     Octstr *output, *var, *temp = NULL;
     int var_len;
@@ -1157,7 +1162,7 @@
 		octstr_destroy(temp);
 	    }
 	  
-	    if ((var_len = parse_variable(ostr, pos, &var, wbxml)) > 0)	{
+	    if ((var_len = parse_variable(ostr, pos, default_esc, &var, wbxml)) > 0)	{
 		if (octstr_len(var) > 0) {
 		    if (octstr_get_char(var, 0) == '$')
 			/*
@@ -1563,7 +1568,7 @@
 	return FAILED;
     }
 
-    ret = check_variable_syntax(name);
+    ret = check_variable_syntax(name, NOESC);
 
     octstr_destroy(name);
     return ret;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.