External DTD support. (but wrapped in #ifdef EXTERNAL_ENTITY_SUPPORT)

This commit is contained in:
cata%netscape.com 1999-06-15 23:20:01 +00:00
Родитель a96881d80d
Коммит 7e287d56b0
12 изменённых файлов: 296 добавлений и 0 удалений

Просмотреть файл

@ -160,6 +160,9 @@ typedef struct {
int complete;
int standalone;
const XML_Char *base;
#ifdef EXTERNAL_ENTITY_SUPPORT
const XML_Char *systemId;
#endif
PREFIX defaultPrefix;
} DTD;
@ -270,6 +273,9 @@ typedef struct {
XML_CharacterDataHandler characterDataHandler;
XML_ProcessingInstructionHandler processingInstructionHandler;
XML_CommentHandler commentHandler;
#ifdef EXTERNAL_ENTITY_SUPPORT
XML_ExternalDTDLoader externalDTDLoader;
#endif
XML_StartCdataSectionHandler startCdataSectionHandler;
XML_EndCdataSectionHandler endCdataSectionHandler;
XML_DefaultHandler defaultHandler;
@ -326,6 +332,9 @@ typedef struct {
#define characterDataHandler (((Parser *)parser)->characterDataHandler)
#define processingInstructionHandler (((Parser *)parser)->processingInstructionHandler)
#define commentHandler (((Parser *)parser)->commentHandler)
#ifdef EXTERNAL_ENTITY_SUPPORT
#define externalDTDLoader (((Parser *)parser)->externalDTDLoader)
#endif
#define startCdataSectionHandler (((Parser *)parser)->startCdataSectionHandler)
#define endCdataSectionHandler (((Parser *)parser)->endCdataSectionHandler)
#define defaultHandler (((Parser *)parser)->defaultHandler)
@ -406,6 +415,9 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName)
characterDataHandler = 0;
processingInstructionHandler = 0;
commentHandler = 0;
#ifdef EXTERNAL_ENTITY_SUPPORT
externalDTDLoader = 0;
#endif
startCdataSectionHandler = 0;
endCdataSectionHandler = 0;
defaultHandler = 0;
@ -515,6 +527,9 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
XML_CommentHandler oldCommentHandler = commentHandler;
#ifdef EXTERNAL_ENTITY_SUPPORT
XML_ExternalDTDLoader oldExternalDTDLoader = externalDTDLoader;
#endif
XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
XML_DefaultHandler oldDefaultHandler = defaultHandler;
@ -537,6 +552,9 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
characterDataHandler = oldCharacterDataHandler;
processingInstructionHandler = oldProcessingInstructionHandler;
commentHandler = oldCommentHandler;
#ifdef EXTERNAL_ENTITY_SUPPORT
externalDTDLoader = oldExternalDTDLoader;
#endif
startCdataSectionHandler = oldStartCdataSectionHandler;
endCdataSectionHandler = oldEndCdataSectionHandler;
defaultHandler = oldDefaultHandler;
@ -661,6 +679,14 @@ void XML_SetCommentHandler(XML_Parser parser,
commentHandler = handler;
}
#ifdef EXTERNAL_ENTITY_SUPPORT
void XML_SetExternalDTDLoader(XML_Parser parser,
XML_ExternalDTDLoader loader)
{
externalDTDLoader = loader;
}
#endif
void XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,
XML_EndCdataSectionHandler end)
@ -1930,6 +1956,12 @@ prologProcessor(XML_Parser parser,
const char *end,
const char **nextPtr)
{
#ifdef EXTERNAL_ENTITY_SUPPORT
char * dtdData;
char * dtdNext;
int dtdLen;
#endif
for (;;) {
const char *next;
int tok = XmlPrologTok(encoding, s, end, &next);
@ -1964,8 +1996,36 @@ prologProcessor(XML_Parser parser,
}
break;
case XML_ROLE_DOCTYPE_SYSTEM_ID:
#ifdef EXTERNAL_ENTITY_SUPPORT
dtd.systemId = poolStoreString(&dtd.pool, encoding,
s + encoding->minBytesPerChar,
next - encoding->minBytesPerChar);
if (!dtd.systemId)
return XML_ERROR_NO_MEMORY;
poolFinish(&dtd.pool);
#endif
hadExternalDoctype = 1;
break;
#ifdef EXTERNAL_ENTITY_SUPPORT
case XML_ROLE_DOCTYPE_CLOSE:
if (hadExternalDoctype == 1) {
// if no loader specified, just default (non-hacked) processing
if (externalDTDLoader) {
XmlPrologStateHack(&prologState);
hadExternalDoctype = 0;
dtdLen = externalDTDLoader(dtd.base, dtd.systemId, &dtdData);
if (dtdLen < 0) {
return XML_ERROR_NO_MEMORY;
}
// XXX better error processing
dtdNext = dtdData + dtdLen;
prologProcessor(parser, dtdData, dtdNext, &dtdNext);
// XXX better error processing
}
}
break;
#endif
case XML_ROLE_DOCTYPE_PUBLIC_ID:
case XML_ROLE_ENTITY_PUBLIC_ID:
if (!XmlIsPublicId(encoding, s, next, &eventPtr))

Просмотреть файл

@ -107,6 +107,13 @@ typedef void (*XML_ProcessingInstructionHandler)(void *userData,
/* data is 0 terminated */
typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
//#define EXTERNAL_ENTITY_SUPPORT
#ifdef EXTERNAL_ENTITY_SUPPORT
typedef int (*XML_ExternalDTDLoader)(const XML_Char * base,
const XML_Char * systemId,
char ** data);
#endif
typedef void (*XML_StartCdataSectionHandler)(void *userData);
typedef void (*XML_EndCdataSectionHandler)(void *userData);
@ -271,6 +278,13 @@ void XMLPARSEAPI
XML_SetCommentHandler(XML_Parser parser,
XML_CommentHandler handler);
#ifdef EXTERNAL_ENTITY_SUPPORT
void XMLPARSEAPI
XML_SetExternalDTDLoader(XML_Parser parser,
XML_ExternalDTDLoader loader);
#endif
void XMLPARSEAPI
XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,

Просмотреть файл

@ -1101,3 +1101,10 @@ void XmlPrologStateInit(PROLOG_STATE *state)
{
state->handler = prolog0;
}
#ifdef EXTERNAL_ENTITY_SUPPORT
void XmlPrologStateHack(PROLOG_STATE *state)
{
state->handler = prolog1;
}
#endif

Просмотреть файл

@ -91,6 +91,11 @@ typedef struct prolog_state {
void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *);
//#define EXTERNAL_ENTITY_SUPPORT
#ifdef EXTERNAL_ENTITY_SUPPORT
void XMLTOKAPI XmlPrologStateHack(PROLOG_STATE *);
#endif
#define XmlTokenRole(state, tok, ptr, end, enc) \
(((state)->handler)(state, tok, ptr, end, enc))

Просмотреть файл

@ -30,6 +30,11 @@
#include "nsIParser.h"
#include "prlog.h"
#ifdef EXTERNAL_ENTITY_SUPPORT
#include "nsINetService.h"
#include "nsIServiceManager.h"
#endif
/************************************************************************
And now for the main class -- nsExpatTokenizer...
************************************************************************/
@ -115,6 +120,9 @@ void nsExpatTokenizer::SetupExpatCallbacks(void) {
XML_SetUnparsedEntityDeclHandler(mExpatParser, HandleUnparsedEntityDecl);
XML_SetNotationDeclHandler(mExpatParser, HandleNotationDecl);
XML_SetExternalEntityRefHandler(mExpatParser, HandleExternalEntityRef);
#ifdef EXTERNAL_ENTITY_SUPPORT
XML_SetExternalDTDLoader(mExpatParser, LoadExternalDTD);
#endif
XML_SetUnknownEncodingHandler(mExpatParser, HandleUnknownEncoding, NULL);
}
}
@ -449,6 +457,54 @@ int nsExpatTokenizer::HandleExternalEntityRef(XML_Parser parser,
return result;
}
#ifdef EXTERNAL_ENTITY_SUPPORT
static NS_DEFINE_IID(kNetServiceCID, NS_NETSERVICE_CID);
static NS_DEFINE_IID(kINetServiceIID, NS_INETSERVICE_IID);
int nsExpatTokenizer::LoadExternalDTD(const XML_Char * base,
const XML_Char * systemId,
char ** data)
{
// XXX free resources when not needed anymore & generally clean this code
nsINetService * netService = nsnull;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID, (nsISupports**) &netService);
if (NS_FAILED(res)) {
return -1;
}
// XXX try to compose this using base url
nsIURL * url = nsnull;
nsString * s = new nsString((PRUnichar *)systemId);
res = netService->CreateURL(&url, *s);
if (NS_FAILED(res)) {
return -1;
}
nsIInputStream * in = nsnull;
res = netService->OpenBlockingStream(url, nsnull, &in);
if (NS_FAILED(res)) {
NS_RELEASE(url);
return -1;
}
// XXX yuck!
char * buff = (char *) malloc(1000);
PRUnichar * buff2 = (PRUnichar *) malloc(1000);
PRUint32 len = 0;
PRUint32 j;
res = in->Read(buff, 1000, &len);
for (j=0 ; j<len; j++) buff2[j] = (PRUnichar) buff[j];
NS_RELEASE(url);
NS_RELEASE(in);
*data = (char *)buff2;
return len*2;
}
#endif
int nsExpatTokenizer::HandleUnknownEncoding(void *encodingHandlerData,
const XML_Char *name,
XML_Encoding *info) {

Просмотреть файл

@ -104,6 +104,12 @@ protected:
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
//#define EXTERNAL_ENTITY_SUPPORT
#ifdef EXTERNAL_ENTITY_SUPPORT
static int LoadExternalDTD(const XML_Char * base,
const XML_Char * systemId,
char ** data);
#endif
static int HandleUnknownEncoding(void *encodingHandlerData,
const XML_Char *name,
XML_Encoding *info);

Просмотреть файл

@ -160,6 +160,9 @@ typedef struct {
int complete;
int standalone;
const XML_Char *base;
#ifdef EXTERNAL_ENTITY_SUPPORT
const XML_Char *systemId;
#endif
PREFIX defaultPrefix;
} DTD;
@ -270,6 +273,9 @@ typedef struct {
XML_CharacterDataHandler characterDataHandler;
XML_ProcessingInstructionHandler processingInstructionHandler;
XML_CommentHandler commentHandler;
#ifdef EXTERNAL_ENTITY_SUPPORT
XML_ExternalDTDLoader externalDTDLoader;
#endif
XML_StartCdataSectionHandler startCdataSectionHandler;
XML_EndCdataSectionHandler endCdataSectionHandler;
XML_DefaultHandler defaultHandler;
@ -326,6 +332,9 @@ typedef struct {
#define characterDataHandler (((Parser *)parser)->characterDataHandler)
#define processingInstructionHandler (((Parser *)parser)->processingInstructionHandler)
#define commentHandler (((Parser *)parser)->commentHandler)
#ifdef EXTERNAL_ENTITY_SUPPORT
#define externalDTDLoader (((Parser *)parser)->externalDTDLoader)
#endif
#define startCdataSectionHandler (((Parser *)parser)->startCdataSectionHandler)
#define endCdataSectionHandler (((Parser *)parser)->endCdataSectionHandler)
#define defaultHandler (((Parser *)parser)->defaultHandler)
@ -406,6 +415,9 @@ XML_Parser XML_ParserCreate(const XML_Char *encodingName)
characterDataHandler = 0;
processingInstructionHandler = 0;
commentHandler = 0;
#ifdef EXTERNAL_ENTITY_SUPPORT
externalDTDLoader = 0;
#endif
startCdataSectionHandler = 0;
endCdataSectionHandler = 0;
defaultHandler = 0;
@ -515,6 +527,9 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
XML_CommentHandler oldCommentHandler = commentHandler;
#ifdef EXTERNAL_ENTITY_SUPPORT
XML_ExternalDTDLoader oldExternalDTDLoader = externalDTDLoader;
#endif
XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
XML_DefaultHandler oldDefaultHandler = defaultHandler;
@ -537,6 +552,9 @@ XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
characterDataHandler = oldCharacterDataHandler;
processingInstructionHandler = oldProcessingInstructionHandler;
commentHandler = oldCommentHandler;
#ifdef EXTERNAL_ENTITY_SUPPORT
externalDTDLoader = oldExternalDTDLoader;
#endif
startCdataSectionHandler = oldStartCdataSectionHandler;
endCdataSectionHandler = oldEndCdataSectionHandler;
defaultHandler = oldDefaultHandler;
@ -661,6 +679,14 @@ void XML_SetCommentHandler(XML_Parser parser,
commentHandler = handler;
}
#ifdef EXTERNAL_ENTITY_SUPPORT
void XML_SetExternalDTDLoader(XML_Parser parser,
XML_ExternalDTDLoader loader)
{
externalDTDLoader = loader;
}
#endif
void XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,
XML_EndCdataSectionHandler end)
@ -1930,6 +1956,12 @@ prologProcessor(XML_Parser parser,
const char *end,
const char **nextPtr)
{
#ifdef EXTERNAL_ENTITY_SUPPORT
char * dtdData;
char * dtdNext;
int dtdLen;
#endif
for (;;) {
const char *next;
int tok = XmlPrologTok(encoding, s, end, &next);
@ -1964,8 +1996,36 @@ prologProcessor(XML_Parser parser,
}
break;
case XML_ROLE_DOCTYPE_SYSTEM_ID:
#ifdef EXTERNAL_ENTITY_SUPPORT
dtd.systemId = poolStoreString(&dtd.pool, encoding,
s + encoding->minBytesPerChar,
next - encoding->minBytesPerChar);
if (!dtd.systemId)
return XML_ERROR_NO_MEMORY;
poolFinish(&dtd.pool);
#endif
hadExternalDoctype = 1;
break;
#ifdef EXTERNAL_ENTITY_SUPPORT
case XML_ROLE_DOCTYPE_CLOSE:
if (hadExternalDoctype == 1) {
// if no loader specified, just default (non-hacked) processing
if (externalDTDLoader) {
XmlPrologStateHack(&prologState);
hadExternalDoctype = 0;
dtdLen = externalDTDLoader(dtd.base, dtd.systemId, &dtdData);
if (dtdLen < 0) {
return XML_ERROR_NO_MEMORY;
}
// XXX better error processing
dtdNext = dtdData + dtdLen;
prologProcessor(parser, dtdData, dtdNext, &dtdNext);
// XXX better error processing
}
}
break;
#endif
case XML_ROLE_DOCTYPE_PUBLIC_ID:
case XML_ROLE_ENTITY_PUBLIC_ID:
if (!XmlIsPublicId(encoding, s, next, &eventPtr))

Просмотреть файл

@ -107,6 +107,13 @@ typedef void (*XML_ProcessingInstructionHandler)(void *userData,
/* data is 0 terminated */
typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
//#define EXTERNAL_ENTITY_SUPPORT
#ifdef EXTERNAL_ENTITY_SUPPORT
typedef int (*XML_ExternalDTDLoader)(const XML_Char * base,
const XML_Char * systemId,
char ** data);
#endif
typedef void (*XML_StartCdataSectionHandler)(void *userData);
typedef void (*XML_EndCdataSectionHandler)(void *userData);
@ -271,6 +278,13 @@ void XMLPARSEAPI
XML_SetCommentHandler(XML_Parser parser,
XML_CommentHandler handler);
#ifdef EXTERNAL_ENTITY_SUPPORT
void XMLPARSEAPI
XML_SetExternalDTDLoader(XML_Parser parser,
XML_ExternalDTDLoader loader);
#endif
void XMLPARSEAPI
XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,

Просмотреть файл

@ -1101,3 +1101,10 @@ void XmlPrologStateInit(PROLOG_STATE *state)
{
state->handler = prolog0;
}
#ifdef EXTERNAL_ENTITY_SUPPORT
void XmlPrologStateHack(PROLOG_STATE *state)
{
state->handler = prolog1;
}
#endif

Просмотреть файл

@ -91,6 +91,11 @@ typedef struct prolog_state {
void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *);
//#define EXTERNAL_ENTITY_SUPPORT
#ifdef EXTERNAL_ENTITY_SUPPORT
void XMLTOKAPI XmlPrologStateHack(PROLOG_STATE *);
#endif
#define XmlTokenRole(state, tok, ptr, end, enc) \
(((state)->handler)(state, tok, ptr, end, enc))

Просмотреть файл

@ -30,6 +30,11 @@
#include "nsIParser.h"
#include "prlog.h"
#ifdef EXTERNAL_ENTITY_SUPPORT
#include "nsINetService.h"
#include "nsIServiceManager.h"
#endif
/************************************************************************
And now for the main class -- nsExpatTokenizer...
************************************************************************/
@ -115,6 +120,9 @@ void nsExpatTokenizer::SetupExpatCallbacks(void) {
XML_SetUnparsedEntityDeclHandler(mExpatParser, HandleUnparsedEntityDecl);
XML_SetNotationDeclHandler(mExpatParser, HandleNotationDecl);
XML_SetExternalEntityRefHandler(mExpatParser, HandleExternalEntityRef);
#ifdef EXTERNAL_ENTITY_SUPPORT
XML_SetExternalDTDLoader(mExpatParser, LoadExternalDTD);
#endif
XML_SetUnknownEncodingHandler(mExpatParser, HandleUnknownEncoding, NULL);
}
}
@ -449,6 +457,54 @@ int nsExpatTokenizer::HandleExternalEntityRef(XML_Parser parser,
return result;
}
#ifdef EXTERNAL_ENTITY_SUPPORT
static NS_DEFINE_IID(kNetServiceCID, NS_NETSERVICE_CID);
static NS_DEFINE_IID(kINetServiceIID, NS_INETSERVICE_IID);
int nsExpatTokenizer::LoadExternalDTD(const XML_Char * base,
const XML_Char * systemId,
char ** data)
{
// XXX free resources when not needed anymore & generally clean this code
nsINetService * netService = nsnull;
nsresult res = nsServiceManager::GetService(kNetServiceCID,
kINetServiceIID, (nsISupports**) &netService);
if (NS_FAILED(res)) {
return -1;
}
// XXX try to compose this using base url
nsIURL * url = nsnull;
nsString * s = new nsString((PRUnichar *)systemId);
res = netService->CreateURL(&url, *s);
if (NS_FAILED(res)) {
return -1;
}
nsIInputStream * in = nsnull;
res = netService->OpenBlockingStream(url, nsnull, &in);
if (NS_FAILED(res)) {
NS_RELEASE(url);
return -1;
}
// XXX yuck!
char * buff = (char *) malloc(1000);
PRUnichar * buff2 = (PRUnichar *) malloc(1000);
PRUint32 len = 0;
PRUint32 j;
res = in->Read(buff, 1000, &len);
for (j=0 ; j<len; j++) buff2[j] = (PRUnichar) buff[j];
NS_RELEASE(url);
NS_RELEASE(in);
*data = (char *)buff2;
return len*2;
}
#endif
int nsExpatTokenizer::HandleUnknownEncoding(void *encodingHandlerData,
const XML_Char *name,
XML_Encoding *info) {

Просмотреть файл

@ -104,6 +104,12 @@ protected:
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
//#define EXTERNAL_ENTITY_SUPPORT
#ifdef EXTERNAL_ENTITY_SUPPORT
static int LoadExternalDTD(const XML_Char * base,
const XML_Char * systemId,
char ** data);
#endif
static int HandleUnknownEncoding(void *encodingHandlerData,
const XML_Char *name,
XML_Encoding *info);