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;