diff options
author | Alexey Shchepin <alexey@process-one.net> | 2003-10-20 18:23:30 +0000 |
---|---|---|
committer | Alexey Shchepin <alexey@process-one.net> | 2003-10-20 18:23:30 +0000 |
commit | f01ea1f0d5d01c949522341f0a649eb27266d07e (patch) | |
tree | 8b5e39cf7fd5d1e0b0b7afbbe6febeeb597b14df | |
parent | * doc/guide.tex: Fixed typo (diff) |
* src/mod_vcard.erl: Added checks for stringprep results
* src/expat_erl.c: Workaround for EI encode_string bug
* src/xml_stream.erl: Slightly changed protocol to expat driver
* src/expat_erl.c: Likewise
* src/mod_configure.erl: Minor fix
SVN Revision: 156
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | doc/guide.html | 6 | ||||
-rw-r--r-- | src/expat_erl.c | 128 | ||||
-rw-r--r-- | src/mod_configure.erl | 3 | ||||
-rw-r--r-- | src/mod_vcard.erl | 72 | ||||
-rw-r--r-- | src/xml_stream.erl | 18 |
6 files changed, 191 insertions, 47 deletions
@@ -1,3 +1,14 @@ +2003-10-20 Alexey Shchepin <alexey@sevcom.net> + + * src/mod_vcard.erl: Added checks for stringprep results + + * src/expat_erl.c: Workaround for EI encode_string bug + + * src/xml_stream.erl: Slightly changed protocol to expat driver + * src/expat_erl.c: Likewise + + * src/mod_configure.erl: Minor fix + 2003-10-19 Alexey Shchepin <alexey@sevcom.net> * doc/guide.tex: Fixed typo diff --git a/doc/guide.html b/doc/guide.html index 9bc46851..8430cbd5 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -465,7 +465,7 @@ except admins have traffic limit 1000 b/s. {ssl, [{certfile, "/path/to/ssl.pem"}]}]}, {5269, ejabberd_s2s_in, []}, {8888, ejabberd_service, - [{host, "conference.example.org", [{password, "secret"}]}]} + [{hosts, ["conference.example.org"], [{password, "secret"}]}]} ]}. </PRE> <!--TOC subsubsection Modules--> @@ -807,8 +807,8 @@ Example: <PRE> {modules, [ ... - {mod_disco, [[{extra_domains, ["jit.example.com", - "etc.example.com"]}]]}, + {mod_disco, [{extra_domains, ["jit.example.com", + "etc.example.com"]}]}, ... ]}. </PRE> diff --git a/src/expat_erl.c b/src/expat_erl.c index a1a950e3..82be2307 100644 --- a/src/expat_erl.c +++ b/src/expat_erl.c @@ -5,6 +5,107 @@ #include <ei.h> #include <expat.h> +#define EI_ENCODE_STRING_BUG + +#ifdef EI_ENCODE_STRING_BUG + +/* + * Workaround for EI encode_string bug + */ + +#define put8(s,n) do { \ + (s)[0] = (char)((n) & 0xff); \ + (s) += 1; \ +} while (0) + +#define put16be(s,n) do { \ + (s)[0] = ((n) >> 8) & 0xff; \ + (s)[1] = (n) & 0xff; \ + (s) += 2; \ +} while (0) + +#define put32be(s,n) do { \ + (s)[0] = ((n) >> 24) & 0xff; \ + (s)[1] = ((n) >> 16) & 0xff; \ + (s)[2] = ((n) >> 8) & 0xff; \ + (s)[3] = (n) & 0xff; \ + (s) += 4; \ +} while (0) + +int ei_encode_string_len_fixed(char *buf, int *index, const char *p, int len) +{ + char *s = buf + *index; + char *s0 = s; + int i; + + if (len <= 0xffff) { + if (!buf) s += 3; + else { + put8(s,ERL_STRING_EXT); + put16be(s,len); + memmove(s,p,len); /* unterminated string */ + } + s += len; + } + else { + if (!buf) s += 6 + (2*len); + else { + /* strings longer than 65535 are encoded as lists */ + put8(s,ERL_LIST_EXT); + put32be(s,len); + + for (i=0; i<len; i++) { + put8(s,ERL_SMALL_INTEGER_EXT); + put8(s,p[i]); + } + + put8(s,ERL_NIL_EXT); + } + } + + *index += s-s0; + + return 0; +} + +int ei_encode_string_fixed(char *buf, int *index, const char *p) +{ + return ei_encode_string_len_fixed(buf, index, p, strlen(p)); +} + +int ei_x_encode_string_len_fixed(ei_x_buff* x, const char* s, int len) +{ + int i = x->index; + ei_encode_string_len_fixed(NULL, &i, s, len); + if (!x_fix_buff(x, i)) + return -1; + return ei_encode_string_len_fixed(x->buff, &x->index, s, len); +} + +int ei_x_encode_string_fixed(ei_x_buff* x, const char* s) +{ + return ei_x_encode_string_len_fixed(x, s, strlen(s)); +} + +#else + +#define ei_encode_string_len_fixed(buf, index, p, len) \ + ei_encode_string_len(buf, index, p, len) +#define ei_encode_string_fixed(buf, index, p) \ + ei_encode_string(buf, index, p) +#define ei_x_encode_string_len_fixed(x, s, len) \ + ei_x_encode_string_len(x, s, len) +#define ei_x_encode_string_fixed(x, s) \ + ei_x_encode_string(x, s) + +#endif + +#define XML_START 0 +#define XML_END 1 +#define XML_CDATA 2 +#define XML_ERROR 3 + + typedef struct { ErlDrvPort port; XML_Parser parser; @@ -19,19 +120,19 @@ void *erlXML_StartElementHandler(expat_data *d, ei_x_new_with_version(&buf); ei_x_encode_tuple_header(&buf, 2); - ei_x_encode_atom(&buf, "xmlstart"); + ei_x_encode_long(&buf, XML_START); ei_x_encode_tuple_header(&buf, 2); - ei_x_encode_string(&buf, name); + ei_x_encode_string_fixed(&buf, name); for (i = 0; atts[i]; i += 2) {} ei_x_encode_list_header(&buf, i/2); - + for (i = 0; atts[i]; i += 2) { ei_x_encode_tuple_header(&buf, 2); - ei_x_encode_string(&buf, atts[i]); - ei_x_encode_string(&buf, atts[i+1]); + ei_x_encode_string_fixed(&buf, atts[i]); + ei_x_encode_string_fixed(&buf, atts[i+1]); } ei_x_encode_empty_list(&buf); @@ -48,8 +149,8 @@ void *erlXML_EndElementHandler(expat_data *d, ei_x_new_with_version(&buf); ei_x_encode_tuple_header(&buf, 2); - ei_x_encode_atom(&buf, "xmlend"); - ei_x_encode_string(&buf, name); + ei_x_encode_long(&buf, XML_END); + ei_x_encode_string_fixed(&buf, name); driver_output(d->port, buf.buff, buf.index); ei_x_free(&buf); @@ -64,8 +165,8 @@ void *erlXML_CharacterDataHandler(expat_data *d, ei_x_new_with_version(&buf); ei_x_encode_tuple_header(&buf, 2); - ei_x_encode_atom(&buf, "xmlcdata"); - ei_x_encode_string_len(&buf, s, len); + ei_x_encode_long(&buf, XML_CDATA); + ei_x_encode_string_len_fixed(&buf, s, len); driver_output(d->port, buf.buff, buf.index); ei_x_free(&buf); @@ -104,11 +205,6 @@ static void expat_erl_output(ErlDrvData handle, char *buff, int bufflen) char *errstring; ei_x_buff buf; - /*buff[bufflen] = 0; - - fprintf(stderr, "RCVD: '%s'\n", buff); - fflush(stderr);*/ - res = XML_Parse(d->parser, buff, bufflen, 0); if(!res) @@ -118,10 +214,10 @@ static void expat_erl_output(ErlDrvData handle, char *buff, int bufflen) ei_x_new_with_version(&buf); ei_x_encode_tuple_header(&buf, 2); - ei_x_encode_atom(&buf, "xmlerror"); + ei_x_encode_long(&buf, XML_ERROR); ei_x_encode_tuple_header(&buf, 2); ei_x_encode_long(&buf, errcode); - ei_x_encode_string(&buf, errstring); + ei_x_encode_string_fixed(&buf, errstring); driver_output(d->port, buf.buff, buf.index); ei_x_free(&buf); diff --git a/src/mod_configure.erl b/src/mod_configure.erl index 9702b83f..94dad76f 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -568,7 +568,8 @@ set_form(["running nodes", ENode, "import", "dir"], Lang, XData) -> false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> - rpc:call(Node, jd2ejd, import_dir, [String]); + rpc:call(Node, jd2ejd, import_dir, [String]), + {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 4a5910ca..70e54caf 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -84,7 +84,7 @@ loop() -> end. -process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> +process_local_iq(_From, _To, {iq, ID, Type, XMLNS, SubEl}) -> case Type of set -> {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; @@ -128,7 +128,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> lists:map(fun(R) -> R#vcard.vcard end, Rs); - {aborted, Reason} -> + {aborted, _Reason} -> [] end, {iq, ID, result, XMLNS, Els} @@ -160,7 +160,22 @@ set_vcard(User, VCARD) -> LOrgName = stringprep:tolower(OrgName), LOrgUnit = stringprep:tolower(OrgUnit), - F = fun() -> + if + (LUser == error) or + (LFN == error) or + (LFamily == error) or + (LGiven == error) or + (LMiddle == error) or + (LNickname == error) or + (LBDay == error) or + (LCTRY == error) or + (LLocality == error) or + (LEMail == error) or + (LOrgName == error) or + (LOrgUnit == error) -> + {error, badarg}; + true -> + F = fun() -> mnesia:write(#vcard{user = LUser, vcard = VCARD}), mnesia:write( #vcard_search{user = User, luser = LUser, @@ -176,8 +191,9 @@ set_vcard(User, VCARD) -> orgname = OrgName, lorgname = LOrgName, orgunit = OrgUnit, lorgunit = LOrgUnit }) - end, - mnesia:transaction(F). + end, + mnesia:transaction(F) + end. -define(TLFIELD(Type, Label, Var), {xmlelement, "field", [{"type", Type}, @@ -310,7 +326,7 @@ do_route(From, To, Packet) -> end end. -find_xdata_el({xmlelement, Name, Attrs, SubEls}) -> +find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> @@ -454,20 +470,36 @@ set_vcard_t(R, _) -> LOrgName = stringprep:tolower(OrgName), LOrgUnit = stringprep:tolower(OrgUnit), - mnesia:write( - #vcard_search{user = User, luser = LUser, - fn = FN, lfn = LFN, - family = Family, lfamily = LFamily, - given = Given, lgiven = LGiven, - middle = Middle, lmiddle = LMiddle, - nickname = Nickname, lnickname = LNickname, - bday = BDay, lbday = LBDay, - ctry = CTRY, lctry = LCTRY, - locality = Locality, llocality = LLocality, - email = EMail, lemail = LEMail, - orgname = OrgName, lorgname = LOrgName, - orgunit = OrgUnit, lorgunit = LOrgUnit - }). + if + (LUser == error) or + (LFN == error) or + (LFamily == error) or + (LGiven == error) or + (LMiddle == error) or + (LNickname == error) or + (LBDay == error) or + (LCTRY == error) or + (LLocality == error) or + (LEMail == error) or + (LOrgName == error) or + (LOrgUnit == error) -> + {error, badarg}; + true -> + mnesia:write( + #vcard_search{user = User, luser = LUser, + fn = FN, lfn = LFN, + family = Family, lfamily = LFamily, + given = Given, lgiven = LGiven, + middle = Middle, lmiddle = LMiddle, + nickname = Nickname, lnickname = LNickname, + bday = BDay, lbday = LBDay, + ctry = CTRY, lctry = LCTRY, + locality = Locality, llocality = LLocality, + email = EMail, lemail = LEMail, + orgname = OrgName, lorgname = LOrgName, + orgunit = OrgUnit, lorgunit = LOrgUnit + }) + end. reindex_vcards() -> diff --git a/src/xml_stream.erl b/src/xml_stream.erl index bb377615..4d7f80d4 100644 --- a/src/xml_stream.erl +++ b/src/xml_stream.erl @@ -12,6 +12,11 @@ -export([start/1, init/1, send_text/2]). +-define(XML_START, 0). +-define(XML_END, 1). +-define(XML_CDATA, 2). +-define(XML_ERROR, 3). + start(CallbackPid) -> spawn(?MODULE, init, [CallbackPid]). @@ -22,24 +27,23 @@ init(CallbackPid) -> loop(CallbackPid, Port, Stack) -> receive {Port, {data, Bin}} -> - %CallbackPid ! binary_to_term(Bin), Data = binary_to_term(Bin), loop(CallbackPid, Port, process_data(CallbackPid, Stack, Data)); - {From, {send, Str}} -> + {_From, {send, Str}} -> Port ! {self(), {command, Str}}, loop(CallbackPid, Port, Stack) end. process_data(CallbackPid, Stack, Data) -> case Data of - {xmlstart, {Name, Attrs}} -> + {?XML_START, {Name, Attrs}} -> if Stack == [] -> gen_fsm:send_event(CallbackPid, {xmlstreamstart, Name, Attrs}); true -> true end, [{xmlelement, Name, Attrs, []} | Stack]; - {xmlend, EndName} -> + {?XML_END, EndName} -> case Stack of [{xmlelement, Name, Attrs, Els} | Tail] -> NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)}, @@ -56,10 +60,10 @@ process_data(CallbackPid, Stack, Data) -> Tail end end; - {xmlcdata, CData} -> + {?XML_CDATA, CData} -> add_subelement({xmlcdata, CData}, Stack); - {xmlerror, Err} -> gen_fsm:send_event(CallbackPid, - {xmlstreamerror, Err}) + {?XML_ERROR, Err} -> gen_fsm:send_event(CallbackPid, + {xmlstreamerror, Err}) end. |