Commit 5972b56a authored by Olivier Bertrand's avatar Olivier Bertrand

- Fix conversion bug for MS-DOM XML tables. The node content was written

  and read as if the table DATA_CHARSET was ANSI instead of UTF-8. Warning
  are now provided when the read content of a node is truncated.

modified:
  storage/connect/domdoc.cpp
  storage/connect/domdoc.h
  storage/connect/libdoc.cpp
  storage/connect/libdoc.h
  storage/connect/plgxml.h
  storage/connect/tabxml.cpp

- Conditional compilation of pre_create depending on the MARIADB setting.

modified:
  storage/connect/ha_connect.cc
  storage/connect/ha_connect.h
parent 8c8fe2f3
...@@ -295,16 +295,41 @@ PXNODE DOMNODE::GetChild(PGLOBAL g) ...@@ -295,16 +295,41 @@ PXNODE DOMNODE::GetChild(PGLOBAL g)
/******************************************************************/ /******************************************************************/
/* Return the content of a node and subnodes. */ /* Return the content of a node and subnodes. */
/******************************************************************/ /******************************************************************/
char *DOMNODE::GetText(char *buf, int len) RCODE DOMNODE::GetContent(PGLOBAL g, char *buf, int len)
{ {
RCODE rc = RC_OK;
// Nodep can be null for a missing HTML table column // Nodep can be null for a missing HTML table column
if (Nodep) if (Nodep) {
strncpy(buf, Nodep->text, len); if (!WideCharToMultiByte(CP_UTF8, 0, Nodep->text, -1,
else buf, len, NULL, NULL)) {
DWORD lsr = GetLastError();
switch (lsr) {
case 0:
case ERROR_INSUFFICIENT_BUFFER: // 122L
sprintf(g->Message, "Truncated %s content", GetName(g));
rc = RC_INFO;
break;
case ERROR_NO_UNICODE_TRANSLATION: // 1113L
sprintf(g->Message, "Invalid character(s) in %s content",
GetName(g));
rc = RC_INFO;
break;
default:
sprintf(g->Message, "System error getting %s content",
GetName(g));
rc = RC_FX;
break;
} // endswitch
} // endif
} else
*buf = '\0'; *buf = '\0';
return buf; return rc;
} // end of GetText } // end of GetContent
/******************************************************************/ /******************************************************************/
/* Set the text content of an attribute. */ /* Set the text content of an attribute. */
...@@ -319,8 +344,8 @@ bool DOMNODE::SetContent(PGLOBAL g, char *txtp, int len) ...@@ -319,8 +344,8 @@ bool DOMNODE::SetContent(PGLOBAL g, char *txtp, int len)
Len = len; Len = len;
} // endif len } // endif len
if (!MultiByteToWideChar(CP_ACP, 0, txtp, strlen(txtp) + 1, if (!MultiByteToWideChar(CP_UTF8, 0, txtp, strlen(txtp) + 1,
Ws, Len + 1)) { Ws, Len + 1)) {
sprintf(g->Message, MSG(WS_CONV_ERR), txtp); sprintf(g->Message, MSG(WS_CONV_ERR), txtp);
return true; return true;
} // endif } // endif
......
...@@ -71,7 +71,7 @@ class DOMNODE : public XMLNODE { ...@@ -71,7 +71,7 @@ class DOMNODE : public XMLNODE {
virtual PXNODE GetChild(PGLOBAL g); virtual PXNODE GetChild(PGLOBAL g);
// Methods // Methods
virtual char *GetText(char *buf, int len); virtual RCODE GetContent(PGLOBAL g, char *buf, int len);
virtual bool SetContent(PGLOBAL g, char *txtp, int len); virtual bool SetContent(PGLOBAL g, char *txtp, int len);
virtual PXNODE Clone(PGLOBAL g, PXNODE np); virtual PXNODE Clone(PGLOBAL g, PXNODE np);
virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp); virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp);
......
...@@ -153,7 +153,7 @@ extern "C" char nmfile[]; ...@@ -153,7 +153,7 @@ extern "C" char nmfile[];
extern "C" char pdebug[]; extern "C" char pdebug[];
extern "C" { extern "C" {
char version[]= "Version 1.01.0002 February 19, 2013"; char version[]= "Version 1.01.0003 March 02, 2013";
#if defined(XMSG) #if defined(XMSG)
char msglang[]; // Default message language char msglang[]; // Default message language
...@@ -3195,6 +3195,7 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key, ...@@ -3195,6 +3195,7 @@ ha_rows ha_connect::records_in_range(uint inx, key_range *min_key,
DBUG_RETURN(rows); DBUG_RETURN(rows);
} // end of records_in_range } // end of records_in_range
#if defined(MARIADB)
/** /**
Convert an ISO-8859-1 column name to UTF-8 Convert an ISO-8859-1 column name to UTF-8
*/ */
...@@ -3657,6 +3658,7 @@ bool ha_connect::pre_create(THD *thd, HA_CREATE_INFO *create_info, ...@@ -3657,6 +3658,7 @@ bool ha_connect::pre_create(THD *thd, HA_CREATE_INFO *create_info,
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return true; return true;
} // end of pre_create } // end of pre_create
#endif // MARIADB
/** /**
@brief @brief
......
...@@ -335,7 +335,9 @@ const char *GetValStr(OPVAL vop, bool neg); ...@@ -335,7 +335,9 @@ const char *GetValStr(OPVAL vop, bool neg);
ha_rows records_in_range(uint inx, key_range *min_key, ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key); key_range *max_key);
int delete_table(const char *from); int delete_table(const char *from);
#if defined(MARIADB)
bool pre_create(THD *thd, HA_CREATE_INFO *crt_info, void *alt_info); bool pre_create(THD *thd, HA_CREATE_INFO *crt_info, void *alt_info);
#endif // MARIADB
int create(const char *name, TABLE *form, int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required HA_CREATE_INFO *create_info); ///< required
bool check_if_incompatible_data(HA_CREATE_INFO *info, bool check_if_incompatible_data(HA_CREATE_INFO *info,
...@@ -347,6 +349,7 @@ const char *GetValStr(OPVAL vop, bool neg); ...@@ -347,6 +349,7 @@ const char *GetValStr(OPVAL vop, bool neg);
protected: protected:
char *GetListOption(const char *opname, const char *oplist, const char *def= NULL); char *GetListOption(const char *opname, const char *oplist, const char *def= NULL);
#if defined(MARIADB)
char *encode(PGLOBAL g, char *cnm); char *encode(PGLOBAL g, char *cnm);
bool add_fields(THD *thd, void *alter_info, bool add_fields(THD *thd, void *alter_info,
LEX_STRING *field_name, LEX_STRING *field_name,
...@@ -361,6 +364,7 @@ const char *GetValStr(OPVAL vop, bool neg); ...@@ -361,6 +364,7 @@ const char *GetValStr(OPVAL vop, bool neg);
// uint uint_geom_type, // uint uint_geom_type,
void *vcol_info, void *vcol_info,
engine_option_value *create_options); engine_option_value *create_options);
#endif // MARIADB
// Members // Members
static ulong num; // Tracable handler number static ulong num; // Tracable handler number
......
...@@ -463,8 +463,10 @@ PXNODE XML2NODE::GetChild(PGLOBAL g) ...@@ -463,8 +463,10 @@ PXNODE XML2NODE::GetChild(PGLOBAL g)
/******************************************************************/ /******************************************************************/
/* Return the content of a node and subnodes. */ /* Return the content of a node and subnodes. */
/******************************************************************/ /******************************************************************/
char *XML2NODE::GetText(char *buf, int len) RCODE XML2NODE::GetContent(PGLOBAL g, char *buf, int len)
{ {
RCODE rc = RC_OK;
if (Content) if (Content)
xmlFree(Content); xmlFree(Content);
...@@ -474,18 +476,24 @@ char *XML2NODE::GetText(char *buf, int len) ...@@ -474,18 +476,24 @@ char *XML2NODE::GetText(char *buf, int len)
bool b = false; bool b = false;
// Copy content eliminating extra characters // Copy content eliminating extra characters
for (; *p1 && (p2 - buf) < len; p1++) for (; *p1; p1++)
if (strchr(extra, *p1)) { if ((p2 - buf) < len) {
if (b) { if (strchr(extra, *p1)) {
// This to have one blank between sub-nodes if (b) {
*p2++ = ' '; // This to have one blank between sub-nodes
b = false; *p2++ = ' ';
} // endif b b = false;
} // endif b
} else {
*p2++ = *p1;
b = true;
} // endif p1
} else { } else {
*p2++ = *p1; sprintf(g->Message, "Truncated %s content", Nodep->name);
b = true; rc = RC_INFO;
} // endif p1 } // endif len
*p2 = 0; *p2 = 0;
...@@ -497,7 +505,7 @@ char *XML2NODE::GetText(char *buf, int len) ...@@ -497,7 +505,7 @@ char *XML2NODE::GetText(char *buf, int len)
} else } else
*buf = '\0'; *buf = '\0';
return buf; return rc;
} // end of GetText } // end of GetText
/******************************************************************/ /******************************************************************/
......
...@@ -80,7 +80,7 @@ class XML2NODE : public XMLNODE { ...@@ -80,7 +80,7 @@ class XML2NODE : public XMLNODE {
virtual PXNODE GetChild(PGLOBAL g); virtual PXNODE GetChild(PGLOBAL g);
// Methods // Methods
virtual char *GetText(char *buf, int len); virtual RCODE GetContent(PGLOBAL g, char *buf, int len);
virtual bool SetContent(PGLOBAL g, char *txtp, int len); virtual bool SetContent(PGLOBAL g, char *txtp, int len);
virtual PXNODE Clone(PGLOBAL g, PXNODE np); virtual PXNODE Clone(PGLOBAL g, PXNODE np);
virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp); virtual PXLIST GetChildElements(PGLOBAL g, char *xp, PXLIST lp);
......
...@@ -110,7 +110,7 @@ class XMLNODE : public BLOCK { ...@@ -110,7 +110,7 @@ class XMLNODE : public BLOCK {
virtual PXNODE GetChild(PGLOBAL) = 0; virtual PXNODE GetChild(PGLOBAL) = 0;
// Methods // Methods
virtual char *GetText(char *, int) = 0; virtual RCODE GetContent(PGLOBAL, char *, int) = 0;
virtual bool SetContent(PGLOBAL, char *, int) = 0; virtual bool SetContent(PGLOBAL, char *, int) = 0;
virtual PXNODE Clone(PGLOBAL, PXNODE) = 0; virtual PXNODE Clone(PGLOBAL, PXNODE) = 0;
virtual PXLIST GetChildElements(PGLOBAL, char * = NULL, PXLIST = NULL) = 0; virtual PXLIST GetChildElements(PGLOBAL, char * = NULL, PXLIST = NULL) = 0;
......
...@@ -1212,7 +1212,16 @@ void XMLCOL::ReadColumn(PGLOBAL g) ...@@ -1212,7 +1212,16 @@ void XMLCOL::ReadColumn(PGLOBAL g)
} // endif type } // endif type
// Get the Xname value from the XML file // Get the Xname value from the XML file
ValNode->GetText(Valbuf, Long); switch (ValNode->GetContent(g, Valbuf, Long + 1)) {
case RC_OK:
break;
case RC_INFO:
PushWarning(g, Tdbp);
break;
default:
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
} // endswitch
} else } else
*Valbuf = '\0'; *Valbuf = '\0';
...@@ -1405,7 +1414,15 @@ void XMULCOL::ReadColumn(PGLOBAL g) ...@@ -1405,7 +1414,15 @@ void XMULCOL::ReadColumn(PGLOBAL g)
} // endif type } // endif type
// Get the Xname value from the XML file // Get the Xname value from the XML file
ValNode->GetText(p, len); switch (ValNode->GetContent(g, p, len + 1)) {
case RC_OK:
break;
case RC_INFO:
PushWarning(g, Tdbp);
break;
default:
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
} // endswitch
if (!Tdbp->Xpand) { if (!Tdbp->Xpand) {
// Concatenate all values // Concatenate all values
...@@ -1627,7 +1644,15 @@ void XPOSCOL::ReadColumn(PGLOBAL g) ...@@ -1627,7 +1644,15 @@ void XPOSCOL::ReadColumn(PGLOBAL g)
if ((ValNode = Tdbp->Clist->GetItem(g, Rank, Vxnp))) if ((ValNode = Tdbp->Clist->GetItem(g, Rank, Vxnp)))
// Get the column value from the XML file // Get the column value from the XML file
ValNode->GetText(Valbuf, Long); switch (ValNode->GetContent(g, Valbuf, Long + 1)) {
case RC_OK:
break;
case RC_INFO:
PushWarning(g, Tdbp);
break;
default:
longjmp(g->jumper[g->jump_level], TYPE_AM_XML);
} // endswitch
Value->SetValue_psz(Valbuf); Value->SetValue_psz(Valbuf);
Nx = Tdbp->Irow; Nx = Tdbp->Irow;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment