12e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/**
22e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Copyright(c) 2011 Trusted Logic.   All rights reserved.
32e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
42e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * Redistribution and use in source and binary forms, with or without
52e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * modification, are permitted provided that the following conditions
62e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * are met:
72e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
82e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *  * Redistributions of source code must retain the above copyright
92e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    notice, this list of conditions and the following disclaimer.
102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *  * Redistributions in binary form must reproduce the above copyright
112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    notice, this list of conditions and the following disclaimer in
122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    the documentation and/or other materials provided with the
132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    distribution.
142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *  * Neither the name Trusted Logic nor the names of its
152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    contributors may be used to endorse or promote products derived
162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *    from this software without specific prior written permission.
172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley *
182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley */
302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "lib_manifest2.h"
312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include <string.h>
322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define CHAR_CR  (uint8_t)0x0D
342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define CHAR_LF  (uint8_t)0x0A
352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define CHAR_TAB (uint8_t)0x09
362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef LIB_TOOL_IMPLEMENTATION
382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#include "exos_trace.h"
392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define LOG_ERROR(pContext, msg, ...) log_error("%s - line %d: " msg, pContext->pManifestName, pContext->nLine, __VA_ARGS__)
402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic void log_error(const char* msg, ...)
412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_list arg_list;
432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_start(arg_list, msg);
442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   exosTraceVPrintf("LIB_MANIFEST2", EXOS_TRACE_ORG_APPLI, K_PRINT_ERROR_LOG, msg, &arg_list);
452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   va_end(arg_list);
462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley/* No error messages on the target */
492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#ifdef __SYMBIAN32__
502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define LOG_ERROR(pContext...)
512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#else
522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define LOG_ERROR(...)
532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#endif
552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyvoid libManifest2InitContext(
572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LIB_MANIFEST2_CONTEXT* pContext)
582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pContext->nOffset = 0;
602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pContext->nLine = 1;
612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pContext->nSectionStartOffset = 0;
622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define CHARACTER_NAME_FIRST      1
662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define CHARACTER_NAME_SUBSEQUENT 2
672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley#define CHARACTER_SECTION_NAME    3
682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic bool static_checkCharacter(uint8_t x, uint32_t nType)
702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* [A-Za-z0-9] is acceptable for everyone */
722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (x  >= (uint8_t)'a' && x <= (uint8_t)'z')
732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return true;
752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (x >=(uint8_t)'A' && x <= (uint8_t)'Z')
772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return true;
792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (x >= (uint8_t)'0' && x <= (uint8_t)'9')
812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return true;
832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nType == CHARACTER_NAME_FIRST)
852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return false;
872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Subsequent property name or section name characters can be [_.-] */
892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (x == (uint8_t)'_' || x == (uint8_t)'.' || x == (uint8_t)'-')
902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return true;
922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nType == CHARACTER_NAME_SUBSEQUENT)
942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return false;
962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Space is also allowed in section names */
982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (x == (uint8_t)' ')
992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return true;
1012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return false;
1032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
1042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic bool static_sectionNameEqualCaseInsensitive(
1062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t* pName1,
1072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nName1Length,
1082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t* pName2,
1092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nName2Length)
1102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
1112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t i;
1122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nName1Length != nName2Length)
1132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return false;
1152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   for (i = 0; i < nName1Length; i++)
1172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint8_t x1 = pName1[i];
1192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint8_t x2 = pName2[i];
1202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* This code assumes the characters have been checked before */
1222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if ((x1 & ~0x20) != (x2 & ~0x20))
1242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
1252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return false;
1262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
1272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
1282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return true;
1292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
1302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleystatic S_RESULT static_libManifest2GetNextItemInternal(
1322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LIB_MANIFEST2_CONTEXT* pContext,
1332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint8_t** ppName,
1342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint32_t* pNameLength,
1352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint8_t** ppValue,
1362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint32_t* pValueLength)
1372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
1382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   S_RESULT nResult = S_ERROR_BAD_FORMAT;
1392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t* pCurrent = pContext->pManifestContent + pContext->nOffset;
1402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t* pEnd = pContext->pManifestContent + pContext->nManifestLength;
1412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t* pLastNonWhitespaceChar;
1422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nCurrentSequenceCount;
1432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nCurrentChar;
1442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
1452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pContext->nType != LIB_MANIFEST2_TYPE_COMPILED)
1462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
1472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Skip leading BOM if we're at the start */
1482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (pCurrent == pContext->pManifestContent)
1492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
1502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* We're at the start. Skip leading BOM if present */
1512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Note that the UTF-8 encoding of the BOM marker is EF BB BF */
1522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (pContext->nManifestLength >= 3
1532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley             && pCurrent[0] == 0xEF
1542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley             && pCurrent[1] == 0xBB
1552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley             && pCurrent[2] == 0xBF)
1562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
1572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pCurrent += 3;
1582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
1592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
1602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Skip comments and newlines */
1612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      while (pCurrent < pEnd)
1622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
1632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (*pCurrent == (uint8_t)'#')
1642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
1652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* This is the start of a comment. Skip until end of line or end of file */
1662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pCurrent++;
1672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            while (pCurrent < pEnd && *pCurrent != CHAR_LF && *pCurrent != CHAR_CR)
1682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
1692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               if (*pCurrent == 0)
1702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
1712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  LOG_ERROR(pContext, "NUL character forbidden");
1722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  goto error;
1732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
1742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pCurrent++;
1752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
1762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
1772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if (*pCurrent == CHAR_CR)
1782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
1792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Check if a LF follows */
1802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pCurrent++;
1812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (pCurrent < pEnd && *pCurrent == CHAR_LF)
1822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
1832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pCurrent++;
1842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
1852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pContext->nLine++;
1862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
1872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if (*pCurrent == CHAR_LF)
1882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
1892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pCurrent++;
1902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pContext->nLine++;
1912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
1922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if (*pCurrent == ' ' || *pCurrent == '\t')
1932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
1942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* this is the start of a all-whitespace line */
1952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* NOTE: this is not allowed by the current spec: spec update needed */
1962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pCurrent++;
1972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            while (pCurrent < pEnd)
1982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
1992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               if (*pCurrent == CHAR_LF || *pCurrent == CHAR_CR)
2002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
2012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  /* End-of-line reached */
2022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  break;
2032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
2042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               if (! (*pCurrent == ' ' || *pCurrent == '\t'))
2052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
2062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  LOG_ERROR(pContext, "A line starting with whitespaces must contain only whitespaces. Illegal character: 0x%02X", *pCurrent);
2072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  goto error;
2082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
2092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pCurrent++;
2102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
2112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
2122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else
2132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
2142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            break;
2152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
2162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
2172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pCurrent >= pEnd)
2202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* No more properties */
2222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nResult = S_ERROR_ITEM_NOT_FOUND;
2232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      goto error;
2242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pContext->nType == LIB_MANIFEST2_TYPE_SOURCE_WITH_SECTIONS)
2272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (*pCurrent == '[')
2292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
2302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* This is a section descriptor */
2312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pCurrent++;
2322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         *ppName = pCurrent;
2332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         *ppValue = NULL;
2342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         *pValueLength = 0;
2352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         while (true)
2362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
2372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (pCurrent >= pEnd)
2382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
2392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               LOG_ERROR(pContext, "EOF reached within a section name");
2402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               goto error;
2412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
2422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (*pCurrent == ']')
2432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
2442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               /* End of section name */
2452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               *pNameLength = pCurrent - *ppName;
2462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pCurrent++;
2472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               /* Skip spaces and tabs. Note that this is a deviation from the current spec
2492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                 (see SWIS). Spec must be updated */
2502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               while (pCurrent < pEnd)
2512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
2522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  if (*pCurrent == ' ' || *pCurrent == '\t')
2532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
2542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     pCurrent++;
2552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
2562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  else if (*pCurrent == CHAR_CR || *pCurrent == CHAR_LF)
2572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
2582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     /* End of line */
2592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     break;
2602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
2612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  else
2622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  {
2632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     LOG_ERROR(pContext, "Non-space character follows a sectino header: 0x02X", *pCurrent);
2642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  }
2652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
2662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nOffset = pCurrent - pContext->pManifestContent;
2672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nSectionStartOffset = pContext->nOffset;
2682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               return S_SUCCESS;
2692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
2702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Check section name character */
2712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (!static_checkCharacter(*pCurrent, CHARACTER_SECTION_NAME))
2722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
2732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               LOG_ERROR(pContext, "Invalid character for a section name: 0x%02X", *pCurrent);
2742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               goto error;
2752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
2762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pCurrent++;
2772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
2782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
2792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (pContext->nSectionStartOffset == 0)
2812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
2822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* No section has been found yet. This is a bad format */
2832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LOG_ERROR(pContext, "Property found outside any section");
2842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         goto error;
2852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
2862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *ppName = pCurrent;
2892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
2902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Check first character of name is in [A-Za-z0-9] */
2912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (!static_checkCharacter(*pCurrent, CHARACTER_NAME_FIRST))
2922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
2932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LOG_ERROR(pContext, "Invalid first character for a property name: 0x%02X", *pCurrent);
2942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      goto error;
2952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
2962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pCurrent++;
2972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pLastNonWhitespaceChar = pCurrent;
2982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   while (true)
2992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
3002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (pCurrent == pEnd)
3012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
3022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LOG_ERROR(pContext, "EOF reached within a property name");
3032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         goto error;
3042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
3052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (*pCurrent == ':')
3062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
3072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Colon reached */
3082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         break;
3092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
3102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (pContext->nType != LIB_MANIFEST2_TYPE_COMPILED)
3112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
3122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* In source manifest, allow space characters before the colon.
3132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            This is a deviation from the spec. Spec must be updated */
3142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (*pCurrent == ' ' || *pCurrent == '\t')
3152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
3162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pCurrent++;
3172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            continue;
3182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
3192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
3202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (!static_checkCharacter(*pCurrent, CHARACTER_NAME_SUBSEQUENT))
3212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
3222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LOG_ERROR(pContext, "Invalid character for a property name: 0x%02X", *pCurrent);
3232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         goto error;
3242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
3252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (pContext->nType != LIB_MANIFEST2_TYPE_COMPILED)
3262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
3272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Even in a source manifest, property name cannot contain spaces! */
3282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (pCurrent != pLastNonWhitespaceChar)
3292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
3302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "Property name cannot contain spaces");
3312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto error;
3322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
3332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
3342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pCurrent++;
3352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pLastNonWhitespaceChar = pCurrent;
3362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
3372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *pNameLength = pLastNonWhitespaceChar - *ppName;
3382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pCurrent++;
3392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Skip spaces and tabs on the right of the colon */
3402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   while (pCurrent < pEnd && (*pCurrent == ' ' || *pCurrent == '\t'))
3412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
3422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pCurrent++;
3432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
3442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *ppValue = pCurrent;
3452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pLastNonWhitespaceChar = pCurrent-1;
3462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   nCurrentSequenceCount = 0;
3482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   nCurrentChar = 0;
3492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
3502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   while (pCurrent < pEnd)
3512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
3522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t x;
3532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      x = *pCurrent;
3542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if ((x & 0x80) == 0)
3552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
3562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (nCurrentSequenceCount != 0)
3572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
3582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* We were expecting a 10xxxxxx byte: ill-formed UTF-8 */
3592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
3602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto error;
3612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
3622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if (x == 0)
3632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
3642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* The null character is forbidden */
3652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "NUL character forbidden");
3662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto error;
3672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
3682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* We have a well-formed Unicode character */
3692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         nCurrentChar = x;
3702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
3712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else if ((x & 0xC0) == 0xC0)
3722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
3732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Start of a sequence */
3742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (nCurrentSequenceCount != 0)
3752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
3762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* We were expecting a 10xxxxxx byte: ill-formed UTF-8 */
3772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
3782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto error;
3792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
3802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if ((x & 0xE0) == 0xC0)
3812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
3822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* 1 byte follows */
3832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentChar = x & 0x1F;
3842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentSequenceCount = 1;
3852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if ((x & 0x1E) == 0)
3862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
3872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               /* Illegal UTF-8: overlong encoding of character in the [0x00-0x7F] range
3882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  (must use 1-byte encoding, not a 2-byte encoding) */
3892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               LOG_ERROR(pContext, "Invalid UTF-8 sequence");
3902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               goto error;
3912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
3922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
3932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if ((x & 0xF0) == 0xE0)
3942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
3952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* 2 bytes follow */
3962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentChar = x & 0x0F;
3972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentSequenceCount = 2;
3982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
3992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if ((x & 0xF8) == 0xF0)
4002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
4012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* 3 bytes follow */
4022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentChar = x & 0x07;
4032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentSequenceCount = 3;
4042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
4052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else
4062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
4072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Illegal start of sequence */
4082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
4092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto error;
4102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
4112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
4122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else if ((x & 0xC0) == 0x80)
4132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
4142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Continuation byte */
4152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (nCurrentSequenceCount == 0)
4162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
4172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* We were expecting a sequence start, not a continuation byte */
4182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "Invalid UTF-8 sequence");
4192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto error;
4202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
4212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else
4222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
4232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (nCurrentSequenceCount == 2)
4242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
4252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               /* We're in a 3-byte sequence, check that we're not using an overlong sequence */
4262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               if (nCurrentChar == 0 && (x & 0x20) == 0)
4272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
4282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  /* The character starts with at least 5 zero bits, so has fewer than 11 bits. It should
4292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     have used a 2-byte sequence, not a 3-byte sequence */
4302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  LOG_ERROR(pContext, "Invalid UTF-8 sequence");
4312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  goto error;
4322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
4332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
4342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            else if (nCurrentSequenceCount == 3)
4352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
4362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               if (nCurrentChar == 0 && (x & 0x30) == 0)
4372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
4382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  /* The character starts with at least 5 zero bits, so has fewer than 16 bits. It should
4392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                     have used a 3-byte sequence, not a 4-byte sequence */
4402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  LOG_ERROR(pContext, "Invalid UTF-8 sequence");
4412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  goto error;
4422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
4432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
4442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentSequenceCount--;
4452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            nCurrentChar = (nCurrentChar << 6) | (x & 0x3F);
4462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
4472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
4482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else
4492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
4502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Illegal byte */
4512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         LOG_ERROR(pContext, "Invalid UTF-8 sequence");
4522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         goto error;
4532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
4542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (nCurrentSequenceCount == 0)
4552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
4562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* nCurrentChar contains the current Unicode character */
4572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* check character */
4582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if ((nCurrentChar >= 0xD800 && nCurrentChar < 0xE000) || nCurrentChar >= 0x110000)
4592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
4602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Illegal code point */
4612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "Invalid UTF-8 code point 0x%X", nCurrentChar);
4622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto error;
4632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
4642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (*pCurrent == CHAR_CR)
4662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
4672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (pContext->nType == LIB_MANIFEST2_TYPE_COMPILED)
4682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
4692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               /* Check if a LF follows */
4702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pCurrent++;
4712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               if (pCurrent < pEnd && *pCurrent == CHAR_LF)
4722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               {
4732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                  pCurrent++;
4742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               }
4752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nLine++;
4762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
4772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto end;
4782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
4792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else if (*pCurrent == CHAR_LF)
4802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
4812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (pContext->nType == LIB_MANIFEST2_TYPE_COMPILED)
4822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
4832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pCurrent++;
4842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nLine++;
4852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
4862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto end;
4872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
4882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
4892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (*pCurrent != ' ' && *pCurrent != CHAR_TAB)
4902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
4912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* It's a non-whitespace char */
4922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pLastNonWhitespaceChar = pCurrent;
4932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
4942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pCurrent++;
4952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
4962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
4972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   /* Hit the end of the manifest; Check that we're not in the middle of a sequence */
4982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (nCurrentSequenceCount != 0)
4992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      LOG_ERROR(pContext, "File ends in the middle of an UTF-8 sequence");
5012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      goto error;
5022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyend:
5052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *pValueLength = pLastNonWhitespaceChar - *ppValue + 1;
5072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pContext->nOffset = pCurrent - pContext->pManifestContent;
5082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return S_SUCCESS;
5102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleyerror:
5122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *ppName = NULL;
5132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *pNameLength = 0;
5142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *ppValue = NULL;
5152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   *pValueLength = 0;
5162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   return nResult;
5172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
5182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyS_RESULT libManifest2GetNextItem(
5202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LIB_MANIFEST2_CONTEXT* pContext,
5212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint8_t** ppName,
5222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint32_t* pNameLength,
5232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint8_t** ppValue,
5242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   OUT uint32_t* pValueLength)
5252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
5262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   if (pContext->nType == LIB_MANIFEST2_TYPE_COMPILED)
5272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Don't check for duplicates in binary manifests */
5292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return static_libManifest2GetNextItemInternal(
5302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pContext,
5312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         ppName,
5322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pNameLength,
5332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         ppValue,
5342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pValueLength);
5352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
5362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   else
5372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
5382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t nOriginalOffset = pContext->nOffset;
5392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t nOffset;
5402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t nLine;
5412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t nSectionStartOffset;
5422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      S_RESULT nResult;
5432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint8_t* pDupName;
5442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t nDupNameLength;
5452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint8_t* pDupValue;
5462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      uint32_t nDupValueLength;
5472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
5482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* First get the item */
5492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nResult = static_libManifest2GetNextItemInternal(
5502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pContext,
5512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         ppName,
5522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pNameLength,
5532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         ppValue,
5542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pValueLength);
5552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (nResult != S_SUCCESS)
5562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
5572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return nResult;
5582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
5592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Save the state of the parser */
5602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nOffset = pContext->nOffset;
5612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nLine = pContext->nLine;
5622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nSectionStartOffset = pContext->nSectionStartOffset;
5632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (pContext->nType == LIB_MANIFEST2_TYPE_SOURCE)
5642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
5652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pContext->nOffset = 0;
5662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
5672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else if (*ppValue == NULL)
5682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
5692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* The item was a section header. Iterate on all section headers and
5702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            check for duplicates */
5712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pContext->nOffset = 0;
5722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
5732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      else
5742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
5752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (nSectionStartOffset == 0)
5762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
5772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            LOG_ERROR(pContext, "Property definition outside any section");
5782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            goto bad_format;
5792e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
5802e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         /* Iterate only on the properties in the section */
5812e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pContext->nOffset = nSectionStartOffset;
5822e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
5832e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      while (pContext->nOffset < nOriginalOffset)
5842e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
5852e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         static_libManifest2GetNextItemInternal(
5862e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            pContext,
5872e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            &pDupName,
5882e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            &nDupNameLength,
5892e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            &pDupValue,
5902e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            &nDupValueLength);
5912e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (pContext->nType == LIB_MANIFEST2_TYPE_SOURCE_WITH_SECTIONS && *ppValue == NULL)
5922e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
5932e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Check for duplicate section names */
5942e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (pDupValue == NULL
5952e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                &&
5962e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                static_sectionNameEqualCaseInsensitive(
5972e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                   *ppName,
5982e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                   *pNameLength,
5992e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                   pDupName,
6002e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                   nDupNameLength))
6012e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
6022e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nOffset = nOffset;
6032e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nLine = nLine;
6042e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nSectionStartOffset = nSectionStartOffset;
6052e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               LOG_ERROR(pContext, "Duplicate section %.*s", nDupNameLength, pDupName);
6062e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               goto bad_format;
6072e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
6082e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
6092e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         else
6102e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
6112e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            /* Check for duplicate property name */
6122e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            if (nDupNameLength == *pNameLength &&
6132e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley                memcmp(pDupName, *ppName, nDupNameLength) == 0)
6142e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            {
6152e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               /* Duplicated property */
6162e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nOffset = nOffset;
6172e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nLine = nLine;
6182e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               pContext->nSectionStartOffset = nSectionStartOffset;
6192e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               LOG_ERROR(pContext,"Duplicate property %.*s", nDupNameLength, pDupName);
6202e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley               goto bad_format;
6212e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            }
6222e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
6232e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
6242e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Everything's fine. restore context and exit  */
6252e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      /* Restore the context */
6262e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pContext->nOffset = nOffset;
6272e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pContext->nLine = nLine;
6282e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      pContext->nSectionStartOffset = nSectionStartOffset;
6292e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6302e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_SUCCESS;
6312e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckleybad_format:
6322e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      *ppName = NULL;
6332e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      *pNameLength = 0;
6342e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      *ppValue = NULL;
6352e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      *pValueLength = 0;
6362e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      return S_ERROR_BAD_FORMAT;
6372e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
6382e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
6392e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6402e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6412e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan BuckleyS_RESULT libManifest2CheckFormat(
6422e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   LIB_MANIFEST2_CONTEXT* pContext,
6432e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t* pnItemCount)
6442e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley{
6452e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nPropertyCount = 0;
6462e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t* pName;
6472e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nNameLength;
6482e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint8_t* pValue;
6492e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   uint32_t nValueLength;
6502e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   S_RESULT nResult;
6512e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6522e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pContext->nOffset = 0;
6532e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pContext->nLine = 1;
6542e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   pContext->nSectionStartOffset = 0;
6552e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley
6562e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   while (true)
6572e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   {
6582e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nResult = libManifest2GetNextItem(
6592e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         pContext,
6602e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         &pName,
6612e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         &nNameLength,
6622e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         &pValue,
6632e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         &nValueLength);
6642e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (nResult == S_ERROR_ITEM_NOT_FOUND)
6652e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
6662e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         if (pnItemCount != NULL)
6672e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         {
6682e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley            *pnItemCount = nPropertyCount;
6692e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         }
6702e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return S_SUCCESS;
6712e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
6722e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      if (nResult != S_SUCCESS)
6732e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      {
6742e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley         return nResult;
6752e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      }
6762e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley      nPropertyCount++;
6772e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley   }
6782e9e9eca83c3dee85b7815573a8cf1e6d1780741Bryan Buckley}
679