For gSOAP 2.8.11 and earlier versions: Changes in the OpenSSL API can lead to a client-side crash in the gSOAP engine for all gSOAP versions 2.8.11 and earlier. This is fixed in 2.8.12 and later. The fix is to replace tcp_connect() in stdsoap2.c and stdsoap2.cpp with this new tcp_connect.c code that replaces the host name check code that is no longer supported in newer OpenSSL versions (releases 0.9.8 and up).
For support requests, please visit the support page.
soap_reference(struct soap *soap, const void *p, int t)
{ struct soap_plist *pp;
if (!p || (!soap->encodingStyle && !(soap->omode & (SOAP_ENC_DIME|SOAP_ENC_MIME|SOAP_ENC_MTOM|SOAP_XML_GRAPH))) || (soap->omode & SOAP_XML_TREE))
return 1;
and
soap_array_reference(struct soap *soap, const void *p, const struct soap_array
*a, int n, int t)
{ struct soap_plist *pp;
if (!p || !a->__ptr || (!soap->encodingStyle && !(soap->omode & (SOAP_ENC_DIME|SOAP_ENC_MIME|SOAP_ENC_MTOM|SOAP_XML_GRAPH))) || (soap->omode & SOAP_XML_TREE))
return 1;
wsrxClient.cpp wsrxServer.cpp:
$(GSOAP) $(GSFLAGS) -A -pwsrx ../../../../import/wsrm5.h
soap_set_namespaces(copy, soap->namespaces); // REMOVE local_
#ifndef WITH_WIN32 int len = SOAP_BUFLEN; #else int len = SOAP_BUFLEN + 1; /* speeds up windows xfer */ #endifThis should speed up transfers of 64KB and up to a fraction of a second.
if (is_fixedstring(typ))
{ fprintf(fhead,"\nSOAP_FMAC3 char* SOAP_FMAC4 soap_in_%s(struct soap*, const char*, char[], const char*);", c_ident(typ)); fprintf(fout,"\n\nSOAP_FMAC3 char* SOAP_FMAC4 soap_in_%s(struct soap *soap, const char *tag, char a[], const char *type)\n{\tchar *p;\n\tif (soap_instring(soap, tag, &p, type, %s, 1, 0, %d))\n\t\treturn strcpy(a, p);\n\treturn NULL;\n}", c_ident(typ), soap_type(typ), typ->width / ((Tnode*)typ->ref)->width - 1);
return;
for (q = p->list; q; q = r)
{ r = q->next;
if (q->buf)
free((void*)q->buf);
free((void*)q);
}
xsd__duration = #import "custom/ducation.h" | xsd__durationto:
xsd__duration = #import "custom/duration.h" | xsd__duration
QApplication app(argc, argv);or
QCoreApplication app(argc, argv);before the gSOAP call, produced a truncated float that keeps only the integer part. It seems that this could be a locale problem (using decimal . versus ,). For correct locale usage in gSOAP, compile the sources with -DWITH_C_LOCALE.
static int
tcp_select(struct soap *soap, SOAP_SOCKET s, int flags, int timeout)
{ register int r;
struct timeval tv;
fd_set fd[3], *rfd, *sfd, *efd;
soap->errnum = 0;
#ifndef WIN32 // <-- ADD
/* if fd max set size exceeded, use poll() when available */
#if defined(__QNX__) || defined(QNX) /* select() is not MT safe on some QNX */
if (1)
...
#else
{ soap->error = SOAP_FD_EXCEEDED;
return -1;
}
#endif
#endif // <-- ADD
rfd = sfd = efd = NULL;
The following is a fix to improve SSL shutdown speed (stdsoap2.c[pp] line
4630) by replacing SOAP_TCP_SELECT_SND by SOAP_TCP_SELECT_RCV:
{ /*
wait up to 10 seconds for close_notify to be sent by peer (if peer not
present, this avoids calling SSL_shutdown() which has a lengthy return
timeout)
*/
r = tcp_select(soap, soap->socket, SOAP_TCP_SELECT_RCV | SOAP_TCP_SELECT_ERR, 10);
/* put hour and min in range */
T.tm_hour += T.tm_min / 60;
T.tm_min %= 60;
if (T.tm_min < 0)
{ T.tm_min += 60;
T.tm_hour--;
}
T.tm_mday += T.tm_hour / 24;
T.tm_hour %= 24;
if (T.tm_hour < 0)
{ T.tm_hour += 24;
T.tm_mday--;
}
/* note: day of the month may be out of range, timegm() handles it */
static size_t
soap_wsse_verify_nested(struct soap *soap, struct soap_dom_element *dom, const char *URI, const char *tag)
{ size_t count = 0;
Fix for known problems with strtof() on some platforms (e.g. SUSE 11).
#if defined(HAVE_STRTOF_L)
char *r;
*p = strtof_l((char*)s, &r, soap->c_locale);
if (*r)
#elif defined(HAVE_STRTOD_L)
char *r;
*p = (float)strtod_l(s, &r, soap->c_locale);
if (*r)
#elif defined(HAVE_STRTOF)
char *r;
*p = strtof((char*)s, &r);
if (*r)
#elif defined(HAVE_STRTOD)
char *r;
*p = (float)strtod(s, &r);
if (*r)
#endif
with:
#if defined(HAVE_STRTOD_L)
char *r;
*p = (float)strtod_l(s, &r, soap->c_locale);
if (*r)
#elif defined(HAVE_STRTOD)
char *r;
*p = (float)strtod(s, &r);
if (*r)
#endif
Fix for router:
soap_free_temp(soap);with:
soap_free_ns(soap);and download the router.c patch.
if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK))
Fix for wsse plugin API HMAC SHA1 signature verification:
download plugin/wsseapi.h source code
download plugin/wsseapi.c source code
3758c3758 < val = meth->i2v(meth, meth->d2i(NULL, &ext->value->data, ext->value->length), NULL); --- > val = meth->i2v(meth, meth->d2i(NULL, (unsigned const char**)&ext->value->data, ext->value->length), NULL);
{
#ifdef WITH_OPENSSL
...
userid = soap->userid; /* preserve */
passwd = soap->passwd; /* preserve */
if (soap_begin_recv(soap))
{ soap->fclosesocket(soap, (SOAP_SOCKET)fd);
return SOAP_INVALID_SOCKET;
}
soap->userid = userid; /* restore */
soap->passwd = passwd; /* restore */
...
To resolve the problem, change this into:
userid = soap->userid; /* preserve */
passwd = soap->passwd; /* preserve */
if ((soap->error = soap->fparse(soap)))
{ soap->fclosesocket(soap, (SOAP_SOCKET)fd);
return SOAP_INVALID_SOCKET;
}
soap->userid = userid; /* restore */
soap->passwd = passwd; /* restore */
const char *ext_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
if (!strcmp(ext_str, "subjectAltName"))
{ int j;
- unsigned char *data;
+ unsigned const char *data;
STACK_OF(CONF_VALUE) *val;
#define soap_isnan(n) ((double)(n) == DBL_NAN)Either enable isnan checking with -DHAVE_ISNAN or change stdsoap2.h:847 by:
#define soap_isnan(n) (0)
//gsoap ns schema form: qualifiedor:
//gsoap ns schema elementForm: qualified //gsoap ns schema attributeForm: unqualifiedto declare form defaults for elements and attributes (i.e. schema elementFormDefault="qualified" and attributeFormDefault="unqualified").
Repeat this for all your schemas, e.g. ns1, ns2, and so on. The difference is profound. Validating parsers require full element/attribute qualification when the schema form default is "qualified". With the directives above, the gSOAP messages conform to this requirement by producing qualified elements and attributes.
The directive is automatically generated by the wsdl2h importer, so you don't need to do this again by hand. However, if you are using an older version of the wsdl2h importer (prior to 1.1.4) you should either try the new importer OR add these directives to the .h file by hand.
soap_s2short(struct soap *soap, const char *s, short *p)
{ if (s)
{ long n;
char *r;
n = soap_strtol(s, &r, 10);
if (*r || n < -32768 || n > 32767)
return soap->error = SOAP_TYPE;
*p = (char)n;
^^^^^^^^^^^
Should be *p = (short)n
SOAP_FMAC1
int
SOAP_FMAC2
soap_element_begin_in(struct soap *soap, const char *tag)
{ if (tag && *tag == '-')
return SOAP_OK;
if (!soap_peek_element(soap))
{ if (soap->other)
return soap->error = SOAP_TAG_MISMATCH;
if (!(soap->error = soap_match_tag(soap, soap->tag, tag)))
{ if (tag && !soap->encodingStyle) /* ADDED check tag!=NULL */
{ const char *s = strchr(tag, ':');
if (s)
soap_push_default_namespace(soap, tag, s - tag);
}
t[0] = '\0'; /* INSERTED */
if (n > 0)
{ m = 0;
for (i = 0; i < n; i++)
m = (m << 8) | *s++;
for (; i < 3; i++)
m <<= 8;
for (i++; i > 0; m >>= 6)
t[--i] = soap_base64o[m & 0x3F];
for (i = 3; i > n; i--)
t[i] = '=';
t[4] = '\0'; /* MOVED UP */
}
return SOAP_OK;
}
stdsoap2.c / stdsoap2.cpp 2.3.8 change both lines 1155 and 8699 as follows:
{ m = ((unsigned long)((unsigned char*)s)[0] << 16) | ((unsigned long)((unsigned char*)s)[1] << 8) | (unsigned long)((unsigned char*)s)[2];
if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && soap_poll(soap) == SOAP_OK) /* REPLACED */
else if (soap->status != SOAP_STOP) /* REPLACED */
soap->null = 0; soap->position = 0; /* INSERTED */ return SOAP_OK; } /* END OF soap_element() */
if (t && tp->value) /* ADDED tp->value check */
{ if (soap_push_namespace(soap, t, tp->value))
and:
for (tp = soap->attributes; tp; tp = tp->next)
{ if (tp->visible && tp->value) /* ADDED tp->value check */
{ if ((soap->socket >= 0) && FD_ISSET(soap->socket, &sfd))
replace with:
{ if ((soap->socket >= 0) && FD_ISSET(soap->socket, &rfd))
int typeNO = 0; /* unique no. assigned to all types */replace with:
int typeNO = 1; /* unique no. assigned to all types */
soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime_size&3);
return soap->error;
insert two lines:
soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime_size&3);
if (soap->fdimereadclose)
soap->fdimereadclose(soap, h);
return soap->error;
if (!soap->copy && soap_valid_socket(soap->master))
{ closesocket((SOAP_SOCKET)soap->master);
soap->master = SOAP_INVALID_SOCKET;
#ifdef WITH_OPENSSL
if (soap->ctx)
{ SSL_CTX_free(soap->ctx);
soap->ctx = NULL;
}
#endif
replace with:
if (!soap->copy)
{ if (soap_valid_socket(soap->master))
{ closesocket((SOAP_SOCKET)soap->master);
soap->master = SOAP_INVALID_SOCKET;
}
#ifdef WITH_OPENSSL
if (soap->ctx)
{ SSL_CTX_free(soap->ctx);
soap->ctx = NULL;
}
#endif
Below is a list of fixes and patches for some issues with gSOAP 2.2.3 (these patches are integrated in the gSOAP 2.3 beta release):
if (soap_poll(soap))with:
if (!soap->keep_alive || soap_poll(soap))in stdsoap2.cpp function soap_connect() (around line 7500 depending on your release version).
soap_s2double(struct soap *soap, const char *s, double *p)
{ ...
{ char *r;
*p = (float)strtod(s, &r); /* REMOVE THE (float) CAST */
if (*r && sscanf(s, soap->double_format, p) != 1)
return soap->error = SOAP_TYPE_MISMATCH;
}
...
Content-Type: application/dime; charset=us-asciiTo fix this, modify function soap_puthttphdr() in stdsoap2.cpp by replacing "application/dime; charset=us-ascii" with the string "application/dime".