/* function: ResolveBaseUri desc: Can be used to resolve systemID in resolveEntityHandler params: parser - parser object systemID - usually entity->systemID from resolveEntityHandler base - usually base dir from GetBaseDir call (which is called before parsing has been started) returns: pointer to baseuri, i.e. the usage in resolveEntityHandler: XMLCH r[FILENAME_MAX]; XMLCH *uri = ResolveBaseUri(parser, entity->systemID, docbasedir); if (uri != entity->systemID) { strcpy(r, uri); uri = strcat(r, entity->systemID); } ... open the resource here i.e. fopen(r) ... notes: Real accurate base uri handling needs of course somekind of stack, however ResolveBaseUri kind of approach should be sufficient for most cases */ XMLCH *ResolveBaseUri(LPXMLPARSER parser, XMLCH *systemID, XMLCH *base) { XMLCH *s=systemID; for (; *s; s++) { if (*s == ':') return systemID; /* probably absolute */ if (*s == '/' || *s == '\\') break; } s = XMLParser_GetPrefixMapping(parser, "xml:base"); return (s) ? s : base; }
static int GetUriAndBase(LPXMLRUNTIMEATT a, XMLCH **target) { XMLCH *baseuri = XMLParser_GetPrefixMapping(parser, "xml:base"); if (baseuri) { int l1 = strlen(baseuri); int l2 = strlen(a->value); int len = l1+l2+1; *target = malloc(len); ASSERT_MEM_ABORT(*target); memcpy(*target, baseuri, l1); memcpy((*target)+l1, a->value, l2); (*target)[len-1]=0; } else { *target = strdup(a->value); ASSERT_MEM_ABORT(*target); } return 0; }
int RunTest(XMLCONFPARSER *xcp, char *uri) { LPXMLRUNTIMEATT att, tatt; XMLCH testuri[MAX_PATH]; XMLCH xmlbase[MAX_PATH]; XMLCH id[256]; XMLCH *s; FILE *f; RUNPARSERDATA rdata; int result, expect; LPXMLPARSER parser = xcp->runParser; int type; if ((s = XMLParser_GetPrefixMapping(xcp->parser, "xml:base"))) strcpy(xmlbase, s); /* we save current xmlbase (although it shouldn't get modified 'cos main parser isn't running during RunTest()) */ else { /* rmt-e2e-18: External entity containing start of entity declaration is base URI for system identifier, so: */ XMLCH *sysID = XMLParser_GetSystemID(xcp->parser); if (!sysID) xmlbase[0] = '\0'; else GetBaseDir(sysID, xmlbase); } strcpy(testuri, xmlbase); strcat(testuri, uri); puts(testuri); /* resolve basedir for external entities, DTD and for canonxml */ GetBaseDir(testuri, rdata.testbasedir); tatt = XMLParser_GetNamedItem(xcp->parser, "TYPE"); if (tatt) { /* "Nonvalidating parsers must also accept "invalid" testcases, but validating ones must reject them." */ if (!strcmp(tatt->value, "valid")) type = TYPE_VALID; else if (!strcmp(tatt->value, "invalid")) type = TYPE_INVALID; else type = TYPE_OTHER; /* error, not-wf */ } if ((f = fopen(testuri, "rb"))) { #ifdef TEST_VALIDATING xcp->v->UserData = &rdata; xcp->v->UserFlag = type; xcp->v->startElementHandlerFilter = StartElementDetermineValidation; result = XMLParser_ParseValidateDTD(xcp->v, parser, cstream, f, 0); #else parser->UserData = &rdata; result = XMLParser_Parse(parser, cstream, f, 0); #endif fclose(f); } else { fprintf(PFERR, "Error opening file %s\n", testuri); return 0; } xcp->testCount++; /* 1 row columns: ID, TYPE, PASS/FAIL, ERRORSTRING 2 row columns: ENTITIES + OUTPUT in one col, 3 empty cols 3 row: test description, 3 empty cols */ att = XMLParser_GetNamedItem(xcp->parser, "ID"); strcpy(id, (att) ? att->value : "unknown"); fputs((xcp->testCount % 2) ? "<tr bgcolor='#EEEEEE'>" : "<tr>", xcp->pfout); fprintf(xcp->pfout, "<td><a href='%s'>%s</a></td>", testuri, id); if (tatt) { if (type == TYPE_VALID) expect = 1; else if (type == TYPE_INVALID) #ifdef TEST_VALIDATING expect = 0; #else expect = 1; #endif else expect = 0; fprintf(xcp->pfout, "<td>%s</td>", tatt->value); if (result == expect) xcp->testSuccess++; }