| 449 | ATTR_TRAILING_SPACES = -4 |
| 450 | }; |
| 451 | static int validateAttr(const String8& path, const ResTable& table, |
| 452 | const ResXMLParser& parser, |
| 453 | const char* ns, const char* attr, const char* validChars, bool required) |
| 454 | { |
| 455 | size_t len; |
| 456 | |
| 457 | ssize_t index = parser.indexOfAttribute(ns, attr); |
| 458 | const uint16_t* str; |
| 459 | Res_value value; |
| 460 | if (index >= 0 && parser.getAttributeValue(index, &value) >= 0) { |
| 461 | const ResStringPool* pool = &parser.getStrings(); |
| 462 | if (value.dataType == Res_value::TYPE_REFERENCE) { |
| 463 | uint32_t specFlags = 0; |
| 464 | int strIdx; |
| 465 | if ((strIdx=table.resolveReference(&value, 0x10000000, NULL, &specFlags)) < 0) { |
| 466 | fprintf(stderr, "%s:%d: Tag <%s> attribute %s references unknown resid 0x%08x.\n", |
| 467 | path.string(), parser.getLineNumber(), |
| 468 | String8(parser.getElementName(&len)).string(), attr, |
| 469 | value.data); |
| 470 | return ATTR_NOT_FOUND; |
| 471 | } |
| 472 | |
| 473 | pool = table.getTableStringBlock(strIdx); |
| 474 | #if 0 |
| 475 | if (pool != NULL) { |
| 476 | str = pool->stringAt(value.data, &len); |
| 477 | } |
| 478 | printf("***** RES ATTR: %s specFlags=0x%x strIdx=%d: %s\n", attr, |
| 479 | specFlags, strIdx, str != NULL ? String8(str).string() : "???"); |
| 480 | #endif |
| 481 | if ((specFlags&~ResTable_typeSpec::SPEC_PUBLIC) != 0 && false) { |
| 482 | fprintf(stderr, "%s:%d: Tag <%s> attribute %s varies by configurations 0x%x.\n", |
| 483 | path.string(), parser.getLineNumber(), |
| 484 | String8(parser.getElementName(&len)).string(), attr, |
| 485 | specFlags); |
| 486 | return ATTR_NOT_FOUND; |
| 487 | } |
| 488 | } |
| 489 | if (value.dataType == Res_value::TYPE_STRING) { |
| 490 | if (pool == NULL) { |
| 491 | fprintf(stderr, "%s:%d: Tag <%s> attribute %s has no string block.\n", |
| 492 | path.string(), parser.getLineNumber(), |
| 493 | String8(parser.getElementName(&len)).string(), attr); |
| 494 | return ATTR_NOT_FOUND; |
| 495 | } |
| 496 | if ((str=pool->stringAt(value.data, &len)) == NULL) { |
| 497 | fprintf(stderr, "%s:%d: Tag <%s> attribute %s has corrupt string value.\n", |
| 498 | path.string(), parser.getLineNumber(), |
| 499 | String8(parser.getElementName(&len)).string(), attr); |
| 500 | return ATTR_NOT_FOUND; |
| 501 | } |
| 502 | } else { |
| 503 | fprintf(stderr, "%s:%d: Tag <%s> attribute %s has invalid type %d.\n", |
| 504 | path.string(), parser.getLineNumber(), |
| 505 | String8(parser.getElementName(&len)).string(), attr, |
| 506 | value.dataType); |
| 507 | return ATTR_NOT_FOUND; |
| 508 | } |
no test coverage detected