patch: xml and prefs


Subject: patch: xml and prefs
From: WJCarpenter (bill-abisource@carpenter.ORG)
Date: Tue Jul 04 2000 - 18:06:14 CDT


The attached patch is from your "Department of You Didn't Even Know
You Had This Problem". It corrects two related problems in the
processing of preferences. All changes are XP. The patch is a diff
against the 070300 nightly source tarball.

1. Because the preferences file(s) are read and parsed with expat,
XML encoding is honored/enforced on attribute values. For example,
the string "&" would be turned into "&". When preferences are
written by applications, the encoding was not being applied. In other
words, round-tripping wouldn't work and it would be possible for a
user-supplied (heh, or even developer-supplied) preference value to
create a parsing problem in the preferences file. THIS PATCH SUPPLIES
THE XML CHARACTER ENCODING WHEN PREFERENCES ARE WRITTEN. The encoding
is done for the four standard XML required characters, characters with
values less than ' ', and characters greater than 127 (the latter to
preserve 7-bit cleanliness).

2. Default values (supplied by developers in the cross-application
and application-specific header files) are treated as if they have
been read from some other-worldly preferences file, but they haven't
undergone XML parsing like values that really have been read from
files. For consistency and because it is tricky to put UTF8 encodings
for high-valued characters in C++ string literals, XML decoding should
be done on those default strings when they are first encountered.
THIS PATCH PERFORMS XML DECODING ON PREFERENCE DEFAULT VALUES DURING
INITIALIZATION. (Quick show of hands... who knew that Abi preference
values were UTF8 and not just ASCII?)

In case anyone is wondering and can't guess, these changes don't
really matter for the current list of preferences and their defaults,
but upcoming preference values for glyph remapping (smart quotes, et
al) depend on these changes.

-- 
bill@carpenter.ORG (WJCarpenter)    PGP 0x91865119
38 95 1B 69 C9 C6 3D 25    73 46 32 04 69 D6 ED F3

diff -c -r abi-070300-ORIG/src/af/util/xp/ut_string.cpp abi-070300/src/af/util/xp/ut_string.cpp *** abi-070300-ORIG/src/af/util/xp/ut_string.cpp Tue May 16 09:22:43 2000 --- abi-070300/src/af/util/xp/ut_string.cpp Tue Jul 4 09:25:59 2000 *************** *** 760,763 **** --- 760,798 ---- } #endif // --jeff + static void endElement(void *userData, const XML_Char *name) + { + } + + static void startElement(void *userData, const XML_Char *name, const XML_Char **atts) + { + XML_Char **pout = (XML_Char **)userData; + *pout = atts[1]; + } + + XML_Char *UT_decodeXMLstring(XML_Char *in) + { + // There has *got* to be an easier way to do this with expat, but I + // didn't spot it from looking at the expat source code. Anyhow, this + // is just used during init to chomp the preference default value + // strings, so the amount of work done probably doesn't matter too + // much. + const char s1[] = "<fake blah=\""; + const char s2[] = "\"/>"; + XML_Char *out = 0; + XML_Parser parser = 0; + parser = XML_ParserCreate(0); + XML_SetUserData(parser, &out); + XML_SetElementHandler(parser, startElement, endElement); + if (!XML_Parse(parser, s1, sizeof(s1)-1, 0) + || !XML_Parse(parser, in, strlen(in), 0) + || !XML_Parse(parser, s2, sizeof(s2)-1, 0)) + { + UT_DEBUGMSG(("XML parsing error %s; %s:%d\n", XML_ErrorString(XML_GetErrorCode(parser)), __FILE__, __LINE__)); + } + // TODO: who owns the storage for this? + out = strdup(out); + if (parser) XML_ParserFree(parser); + return out; + } diff -c -r abi-070300-ORIG/src/af/util/xp/ut_string.h abi-070300/src/af/util/xp/ut_string.h *** abi-070300-ORIG/src/af/util/xp/ut_string.h Mon Jun 26 14:46:00 2000 --- abi-070300/src/af/util/xp/ut_string.h Sun Jul 2 21:35:35 2000 *************** *** 82,87 **** --- 82,88 ---- UT_UCSChar UT_decodeUTF8char(const XML_Char * p, UT_uint32 len); void UT_decodeUTF8string(const XML_Char * p, UT_uint32 len, UT_GrowBuf * pResult); XML_Char * UT_encodeUTF8char(UT_UCSChar cIn); + XML_Char * UT_decodeXMLstring(XML_Char *pcIn); #define UT_UCS_isdigit(x) (((x) >= '0') && ((x) <= '9')) #define UT_UCS_isupper(x) (((x) >= 'A') && ((x) <= 'Z')) // HACK: not UNICODE-safe diff -c -r abi-070300-ORIG/src/af/xap/xp/xap_Prefs.cpp abi-070300/src/af/xap/xp/xap_Prefs.cpp *** abi-070300-ORIG/src/af/xap/xp/xap_Prefs.cpp Wed May 10 22:04:41 2000 --- abi-070300/src/af/xap/xp/xap_Prefs.cpp Mon Jul 3 12:56:48 2000 *************** *** 24,29 **** --- 24,30 ---- #include <string.h> #include "ut_debugmsg.h" + #include "ut_growbuf.h" #include "xap_Prefs.h" /*****************************************************************/ *************** *** 871,876 **** --- 872,879 ---- "\t**** defaults and adjusted by the installation system defaults. This scheme\n" "\t**** is only written here as a reference. Any schemes following this one\n" "\t**** only list values that deviate from the built-in values.\n" + "\t**** Items values must observe XML encoding for double quote (&quot;),\n" + "\t**** ampersand (&amp;), and angle brackets (&lt; and &gt;).\n" "\t-->\n"), szBuiltinSchemeName); } *************** *** 882,891 **** UT_uint32 j; for (j=0; (p->getNthValue(j,&szKey,&szValue)); j++) { if (bIsBuiltin) { // for the builtin set, we print every value ! fprintf(fp,"\t\t%s=\"%s\"\n",szKey,szValue); } else { --- 885,896 ---- UT_uint32 j; for (j=0; (p->getNthValue(j,&szKey,&szValue)); j++) { + UT_Bool need_print; + need_print = UT_FALSE; if (bIsBuiltin) { // for the builtin set, we print every value ! need_print = UT_TRUE; } else { *************** *** 895,901 **** UT_Bool bHaveBuiltinValue = m_builtinScheme->getValue(szKey,&szBuiltinValue); UT_ASSERT(bHaveBuiltinValue); if (UT_XML_strcmp(szValue,szBuiltinValue) != 0) ! fprintf(fp,"\t\t%s=\"%s\"\n",szKey,szValue); } } --- 900,940 ---- UT_Bool bHaveBuiltinValue = m_builtinScheme->getValue(szKey,&szBuiltinValue); UT_ASSERT(bHaveBuiltinValue); if (UT_XML_strcmp(szValue,szBuiltinValue) != 0) ! need_print = UT_TRUE; ! } ! if (need_print == UT_TRUE) ! { ! // szValue is UTF8. Convert to Unicode and then ! // do XML-encoding of XML-special characters and ! // non-ASCII characters. The printed value ! // strings will get XML parsing and conversion to ! // UTF8 the next time the application reads the ! // prefs file. ! UT_GrowBuf gb; ! UT_decodeUTF8string(szValue, UT_XML_strlen(szValue), &gb); ! UT_uint32 length = gb.getLength(); ! fprintf(fp,"\t\t%s=\"",szKey); ! for (UT_uint32 udex=0; udex<length; ++udex) ! { ! UT_UCSChar ch = *(gb.getPointer(udex)); ! switch (ch) ! { ! case '&': fputs("&amp;", fp); break; ! case '<': fputs("&lt;", fp); break; ! case '>': fputs("&gt;", fp); break; ! case '"': fputs("&quot;", fp); break; ! default: ! if (ch < ' ' || ch >= 128) ! { ! fprintf(fp, "&#x%x;", ch); ! } ! else ! { ! putc(ch, fp); ! } ! } ! } ! fputs("\"\n", fp); } } diff -c -r abi-070300-ORIG/src/af/xap/xp/xap_Prefs_SchemeIds.h abi-070300/src/af/xap/xp/xap_Prefs_SchemeIds.h *** abi-070300-ORIG/src/af/xap/xp/xap_Prefs_SchemeIds.h Thu May 13 11:30:33 1999 --- abi-070300/src/af/xap/xp/xap_Prefs_SchemeIds.h Tue Jul 4 09:43:35 2000 *************** *** 30,36 **** ////////////////////////////////////////////////////////////////////////////////////// // The following are the set of scheme-based application-independent preference keys // and the set of default values for them. Each item must have the XAP_PREF_KEY_ prefix ! // and each value must have the XAP_PREF_DEFAULT_ prefix. // // ***FOR EACH PAIR DEFINED, ADD A 'dcl(basename)' TO THE BOTTOM HALF OF THIS FILE*** // --- 30,38 ---- ////////////////////////////////////////////////////////////////////////////////////// // The following are the set of scheme-based application-independent preference keys // and the set of default values for them. Each item must have the XAP_PREF_KEY_ prefix ! // and each value must have the XAP_PREF_DEFAULT_ prefix. Default values *must* obey ! // XML encoding rules if they contain any double quote (&quot;), ampersand (&amp;), ! // or angle bracket (&lt; and &gt;) characters. // // ***FOR EACH PAIR DEFINED, ADD A 'dcl(basename)' TO THE BOTTOM HALF OF THIS FILE*** // diff -c -r abi-070300-ORIG/src/wp/ap/xp/ap_Prefs.cpp abi-070300/src/wp/ap/xp/ap_Prefs.cpp *** abi-070300-ORIG/src/wp/ap/xp/ap_Prefs.cpp Sat Nov 6 18:01:31 1999 --- abi-070300/src/wp/ap/xp/ap_Prefs.cpp Mon Jul 3 13:05:58 2000 *************** *** 20,25 **** --- 20,27 ---- #include <stdio.h> #include "ap_Prefs.h" #include "xap_App.h" + #include "ut_debugmsg.h" + #include "ut_string.h" /*****************************************************************/ *************** *** 110,118 **** # undef dcl }; for (UT_uint32 k=0; k<NrElements(_t); k++) ! if (!pScheme->setValue(_t[k].m_szKey, _t[k].m_szValue)) goto Failed; addScheme(pScheme); // set the builtin scheme in the base class overlaySystemPrefs(); // so that the base class parser can overlay it. --- 112,126 ---- # undef dcl }; + // Must do XML special character decoding on the default values + // since that will automatically happen in the case of values + // values read from preferences files. for (UT_uint32 k=0; k<NrElements(_t); k++) ! { ! UT_DEBUGMSG(("DEFAULT %s |%s|%s|\n", _t[k].m_szKey, _t[k].m_szValue, UT_decodeXMLstring(_t[k].m_szValue))); ! if (!pScheme->setValue(_t[k].m_szKey, UT_decodeXMLstring(_t[k].m_szValue))) goto Failed; + } addScheme(pScheme); // set the builtin scheme in the base class overlaySystemPrefs(); // so that the base class parser can overlay it. diff -c -r abi-070300-ORIG/src/wp/ap/xp/ap_Prefs_SchemeIds.h abi-070300/src/wp/ap/xp/ap_Prefs_SchemeIds.h *** abi-070300-ORIG/src/wp/ap/xp/ap_Prefs_SchemeIds.h Wed May 17 23:10:07 2000 --- abi-070300/src/wp/ap/xp/ap_Prefs_SchemeIds.h Mon Jul 3 13:09:29 2000 *************** *** 30,36 **** ////////////////////////////////////////////////////////////////////////////// // The following are the set of application-dependent preference keys and the // set of default values for them. Each item must have the AP_PREF_KEY_ prefix ! // and each value must have the AP_PREF_DEFAULT_ prefix. // // ***FOR EACH PAIR DEFINED, ADD A 'dcl(basename)' TO THE BOTTOM HALF OF THIS FILE*** // --- 30,38 ---- ////////////////////////////////////////////////////////////////////////////// // The following are the set of application-dependent preference keys and the // set of default values for them. Each item must have the AP_PREF_KEY_ prefix ! // and each value must have the XAP_PREF_DEFAULT_ prefix. Default values *must* obey ! // XML encoding rules if they contain any double quote (&quot;), ampersand (&amp;), ! // or angle bracket (&lt; and &gt;) characters. // // ***FOR EACH PAIR DEFINED, ADD A 'dcl(basename)' TO THE BOTTOM HALF OF THIS FILE*** //



This archive was generated by hypermail 2b25 : Tue Jul 04 2000 - 18:53:55 CDT