[sr-dev] git:master: xmlrpc(s): option for replacing double lf with crlf

Juha Heinanen jh at tutpro.com
Wed Sep 23 14:37:49 CEST 2009


Andrei Pelinescu-Onciul writes:

 > Added "double_lf_to_crlf" config parameter. When set double LFs in
 > the input xmlrpc strings are replaced with CR LF. This is needed
 > to work around some xmlrpc buggy clients that don't escape CR
 > ('\r' should be escaped to 
 ). When using one of those buggy
 > clients, use double LF as an escape for CR LF and turn this
 >  option on.Turning this option on makes it also more compatible with
 > kamailio tools (kamailio mi xmlrpc always converts double LF to CR
 > LF).

andrei,

that you very much for adding support for those "buggy clients".  if the
clients really are buggy is controversial.  xmlrpc spec has this:

  What characters are allowed in strings? Non-printable characters? Null
  characters? Can a "string" be used to hold an arbitrary chunk of
  binary data?  

  Any characters are allowed in a string except < and &, which are
  encoded as &lt; and &amp;. A string can be used to encode binary data.

many client vendors have interpreted this to mean that \r is a perfectly
valid character in xmlrpc string and need not to be escaped.

-- juha



































































































 >  /* get_* flags: */
 >  #define GET_X_AUTOCONV 1
 >  #define GET_X_NOREPLY 2
 > +#define GET_X_LFLF2CRLF 4  /* replace "\n\n" with "\r\n" */
 >  
 >  /* xml value types */
 >  enum xmlrpc_val_type{
 > @@ -1294,14 +1299,16 @@ static int get_double(double* val, struct xmlrpc_reply* reply,
 >  
 >  /** Convert a parameter encoded in XML-RPC to a zero terminated string.
 >   *
 > - * @param val A pointer to an integer variable where the result will be 
 > -              stored.
 > + * @param val A pointer to a char* variable where the result will be 
 > + *            stored (the result is dynamically allocated, but it's garbage
 > + *            collected, so it doesn't have to be freed)
 >   * @param reply A pointer to XML-RPC reply being constructed (used to indicate
 >   *              conversion errors).
 >   * @param doc A pointer to the XML-RPC request document.
 >   * @param value A pointer to the element containing the parameter to be 
 >   *              converted within the document.
 >   * @param flags : GET_X_AUTOCONV - try autoconverting
 > + *                GET_X_LFLF2CRLF - replace double '\n' with `\r\n'
 >   *                GET_X_NOREPLY - do not reply
 >   * @return <0 on error, 0 on success
 >   */
 > @@ -1360,6 +1367,18 @@ static int get_string(char** val, struct xmlrpc_reply* reply,
 >  	ret=0;
 >  	switch(type){
 >  		case XML_T_STR:
 > +			if (flags & GET_X_LFLF2CRLF){
 > +				p=val_str;
 > +				while(*p){
 > +					if (*p=='\n' && *(p+1)=='\n'){
 > +						*p='\r';
 > +						p+=2;
 > +						continue;
 > +					}
 > +					p++;
 > +				}
 > +			}
 > +			/* no break */
 >  		case XML_T_DATE:  /* no special conversion */
 >  		case XML_T_DOUBLE: /* no special conversion */
 >  			if (add_garbage(JUNK_XMLCHAR, val_str, reply) < 0){
 > @@ -1428,7 +1447,8 @@ static int rpc_scan(rpc_ctx_t* ctx, char* fmt, ...)
 >  	va_start(ap, fmt);
 >  	modifiers=0;
 >  	read = 0;
 > -	f=autoconvert?GET_X_AUTOCONV:0;
 > +	f=(autoconvert?GET_X_AUTOCONV:0) |
 > +		(lflf2crlf?GET_X_LFLF2CRLF:0);
 >  	while(*fmt) {
 >  		if (!ctx->act_param) goto error;
 >  		value = ctx->act_param->xmlChildrenNode;
 > @@ -1737,8 +1757,11 @@ static int rpc_struct_scan(struct rpc_struct* s, char* fmt, ...)
 >  	char* member_name;
 >  	struct xmlrpc_reply* reply;
 >  	int ret;
 > +	int f;
 >  
 >  	read = 0;
 > +	f=(autoconvert?GET_X_AUTOCONV:0) |
 > +		(lflf2crlf?GET_X_LFLF2CRLF:0);
 >  	va_start(ap, fmt);
 >  	while(*fmt) {
 >  		member_name = va_arg(ap, char*);
 > @@ -1751,23 +1774,23 @@ static int rpc_struct_scan(struct rpc_struct* s, char* fmt, ...)
 >  		case 't': /* Date and time */
 >  		case 'd': /* Integer */
 >  			int_ptr = va_arg(ap, int*);
 > -			if (get_int(int_ptr, reply, s->doc, value, 0) < 0) goto error;
 > +			if (get_int(int_ptr, reply, s->doc, value, f) < 0) goto error;
 >  			break;
 >  
 >  		case 'f': /* double */
 >  			double_ptr = va_arg(ap, double*);
 > -			if (get_double(double_ptr, reply, s->doc, value, 0) < 0)
 > +			if (get_double(double_ptr, reply, s->doc, value, f) < 0)
 >  				goto error;
 >  			break;
 >  
 >  		case 's': /* zero terminated string */
 >  			char_ptr = va_arg(ap, char**);
 > -			if (get_string(char_ptr, reply, s->doc, value, 0) < 0) goto error;
 > +			if (get_string(char_ptr, reply, s->doc, value, f) < 0) goto error;
 >  			break;
 >  
 >  		case 'S': /* str structure */
 >  			str_ptr = va_arg(ap, str*);
 > -			if (get_string(&str_ptr->s, reply, s->doc, value, 0) < 0)
 > +			if (get_string(&str_ptr->s, reply, s->doc, value, f) < 0)
 >  				goto error;
 >  			str_ptr->len = strlen(str_ptr->s);
 >  			break;
 > 
 > 
 > _______________________________________________
 > sr-dev mailing list
 > sr-dev at lists.sip-router.org
 > http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev



More information about the sr-dev mailing list