VirtualBox

Ignore:
Timestamp:
Aug 30, 2018 1:58:20 PM (6 years ago)
Author:
vboxsync
Message:

IPRT/json: Made the json parser report error info. Currently we're failing to parse negative numbers, added this to tstRTJson. bugref:9167

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/json.cpp

    r73978 r73979  
    148148    PFNRTJSONTOKENIZERREAD  pfnRead;
    149149    /** Opaque user data. */
    150     void                    *pvUser;
     150    void                   *pvUser;
    151151    /** Current offset into the input stream. */
    152152    size_t                  offInput;
    153153    /** Number of valid bytes in the input buffer. */
    154154    size_t                  cbBuf;
    155     /* Current offset into the input buffer. */
     155    /** Current offset into the input buffer. */
    156156    size_t                  offBuf;
    157157    /** Input cache buffer. */
     
    169169    /** The tokenizer error state. */
    170170    int                     rcTok;
     171    /** Where to return extended error information.*/
     172    PRTERRINFO              pErrInfo;
    171173} RTJSONTOKENIZER;
    172174/** Pointer to a JSON tokenizer. */
     
    253255
    254256/*********************************************************************************************************************************
    255 *   Global variables                                                                                                             *
     257*   Internal Functions                                                                                                           *
    256258*********************************************************************************************************************************/
    257 
    258 static int rtJsonParseValue(PRTJSONTOKENIZER pTokenizer, PRTJSONTOKEN pToken,
    259                             PRTJSONVALINT *ppJsonVal, PRTERRINFO pErrInfo);
     259static int rtJsonParseValue(PRTJSONTOKENIZER pTokenizer, PRTJSONTOKEN pToken, PRTJSONVALINT *ppJsonVal);
     260
    260261
    261262/**
     
    475476    {
    476477        pToken->enmClass = RTJSONTOKENCLASS_INVALID;
    477         rc = VERR_JSON_MALFORMED;
     478        rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "malformed literal '%.6s' (line %zu col %zu)",
     479                           &szLiteral[0], pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    478480    }
    479481
     
    585587                    break;
    586588                default:
    587                     rc = VERR_JSON_MALFORMED;
     589                    rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "bad escape sequence (line %zu col %zu)",
     590                                       pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
     591                    break;
    588592            }
    589593        }
     
    704708    {
    705709        pToken->enmClass = RTJSONTOKENCLASS_INVALID;
    706         rc = VERR_JSON_MALFORMED;
     710        rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "bad token '%c' (line %zu col %zu)",
     711                           ch, pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    707712    }
    708713
     
    720725 * @param   pfnRead         Read callback for the input stream.
    721726 * @param   pvUser          Opaque user data to pass to the callback.
    722  */
    723 static int rtJsonTokenizerInit(PRTJSONTOKENIZER pTokenizer, PFNRTJSONTOKENIZERREAD pfnRead, void *pvUser)
     727 * @param   pErrInfo        Where to return extended error info.
     728 */
     729static int rtJsonTokenizerInit(PRTJSONTOKENIZER pTokenizer, PFNRTJSONTOKENIZERREAD pfnRead, void *pvUser, PRTERRINFO pErrInfo)
    724730{
    725731    pTokenizer->pfnRead      = pfnRead;
     
    734740    pTokenizer->pTokenNext   = &pTokenizer->Token2;
    735741    pTokenizer->rcTok        = VINF_SUCCESS;
     742    pTokenizer->pErrInfo     = pErrInfo;
    736743
    737744    RT_ZERO(pTokenizer->achBuf);
     
    881888 * @param   pTokenizer      The tokenizer to use.
    882889 * @param   pJsonVal        The JSON array value to fill in.
    883  * @param   pErrInfo        Where to store extended error info. Optional.
    884  */
    885 static int rtJsonParseArray(PRTJSONTOKENIZER pTokenizer, PRTJSONVALINT pJsonVal, PRTERRINFO pErrInfo)
     890 */
     891static int rtJsonParseArray(PRTJSONTOKENIZER pTokenizer, PRTJSONVALINT pJsonVal)
    886892{
    887893    int rc = VINF_SUCCESS;
     
    897903    {
    898904        PRTJSONVALINT pVal = NULL;
    899         rc = rtJsonParseValue(pTokenizer, pToken, &pVal, pErrInfo);
     905        rc = rtJsonParseValue(pTokenizer, pToken, &pVal);
    900906        if (RT_SUCCESS(rc))
    901907        {
     
    924930            && !fSkippedSep
    925931            && pToken->enmClass != RTJSONTOKENCLASS_END_ARRAY)
    926             rc = VERR_JSON_MALFORMED;
     932            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "expected end of array (#1) (line %zu col %zu)",
     933                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    927934    }
    928935
     
    936943        }
    937944        else
    938             rc = VERR_JSON_MALFORMED;
     945            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "expected end of array (#2) (line %zu col %zu)",
     946                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    939947    }
    940948
     
    955963 * @param   pTokenizer      The tokenizer to use.
    956964 * @param   pJsonVal        The JSON object value to fill in.
    957  * @param   pErrInfo        Where to store extended error info. Optional.
    958  */
    959 static int rtJsonParseObject(PRTJSONTOKENIZER pTokenizer, PRTJSONVALINT pJsonVal, PRTERRINFO pErrInfo)
     965 */
     966static int rtJsonParseObject(PRTJSONTOKENIZER pTokenizer, PRTJSONVALINT pJsonVal)
    960967{
    961968    int rc = VINF_SUCCESS;
     
    978985            rc = rtJsonTokenizerGetToken(pTokenizer, &pToken);
    979986            if (RT_SUCCESS(rc))
    980                 rc = rtJsonParseValue(pTokenizer, pToken, &pVal, pErrInfo);
     987                rc = rtJsonParseValue(pTokenizer, pToken, &pVal);
    981988            if (RT_SUCCESS(rc))
    982989            {
     
    10121019                    && !fSkippedSep
    10131020                    && pToken->enmClass != RTJSONTOKENCLASS_END_OBJECT)
    1014                     rc = VERR_JSON_MALFORMED;
     1021                    rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "expected end of object (#1) (line %zu col %zu)",
     1022                                       pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    10151023            }
    10161024        }
    10171025        else
    1018             rc = VERR_JSON_MALFORMED;
     1026            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "expected name separator (line %zu col %zu)",
     1027                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    10191028    }
    10201029
     
    10291038        }
    10301039        else
    1031             rc = VERR_JSON_MALFORMED;
     1040            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "expected end of object (#2) (line %zu col %zu)",
     1041                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    10321042    }
    10331043
     
    10531063 * @param   pToken          The token to parse.
    10541064 * @param   ppJsonVal       Where to store the pointer to the JSON value on success.
    1055  * @param   pErrInfo        Where to store extended error info. Optional.
    1056  */
    1057 static int rtJsonParseValue(PRTJSONTOKENIZER pTokenizer, PRTJSONTOKEN pToken,
    1058                             PRTJSONVALINT *ppJsonVal, PRTERRINFO pErrInfo)
     1065 */
     1066static int rtJsonParseValue(PRTJSONTOKENIZER pTokenizer, PRTJSONTOKEN pToken, PRTJSONVALINT *ppJsonVal)
    10591067{
    10601068    int rc = VINF_SUCCESS;
     
    10671075            pVal = rtJsonValueCreate(RTJSONVALTYPE_ARRAY);
    10681076            if (RT_LIKELY(pVal))
    1069                 rc = rtJsonParseArray(pTokenizer, pVal, pErrInfo);
     1077                rc = rtJsonParseArray(pTokenizer, pVal);
    10701078            break;
    10711079        case RTJSONTOKENCLASS_BEGIN_OBJECT:
     
    10731081            pVal = rtJsonValueCreate(RTJSONVALTYPE_OBJECT);
    10741082            if (RT_LIKELY(pVal))
    1075                 rc = rtJsonParseObject(pTokenizer, pVal, pErrInfo);
     1083                rc = rtJsonParseObject(pTokenizer, pVal);
    10761084            break;
    10771085        case RTJSONTOKENCLASS_STRING:
     
    10991107            pVal = rtJsonValueCreate(RTJSONVALTYPE_TRUE);
    11001108            break;
     1109
     1110        case RTJSONTOKENCLASS_INVALID:
     1111            Assert(!pTokenizer->pErrInfo || RTErrInfoIsSet(pTokenizer->pErrInfo));
     1112            rc = VERR_JSON_MALFORMED;
     1113            break;
    11011114        case RTJSONTOKENCLASS_END_ARRAY:
     1115            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "unexpected '}' (line %zu col %zu)",
     1116                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
     1117            break;
    11021118        case RTJSONTOKENCLASS_END_OBJECT:
     1119            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "unexpected ']' (line %zu col %zu)",
     1120                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
     1121            break;
    11031122        case RTJSONTOKENCLASS_NAME_SEPARATOR:
     1123            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "unexpected ':' (line %zu col %zu)",
     1124                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
     1125            break;
    11041126        case RTJSONTOKENCLASS_VALUE_SEPARATOR:
     1127            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "unexpected ',' (line %zu col %zu)",
     1128                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
     1129            break;
    11051130        case RTJSONTOKENCLASS_EOS:
     1131            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "expected end of object (#1) (line %zu col %zu)",
     1132                               pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
     1133            break;
    11061134        default:
    1107             /** @todo Error info */
    1108             rc = VERR_JSON_MALFORMED;
     1135            rc = RTErrInfoSetF(pTokenizer->pErrInfo, VERR_JSON_MALFORMED, "Unexpected token class %d (line %zu col %zu)",
     1136                               pToken->enmClass, pTokenizer->Pos.iLine, pTokenizer->Pos.iChStart);
    11091137            break;
    11101138    }
     
    11291157 * @param   pTokenizer      The tokenizer state.
    11301158 * @param   ppJsonVal       Where to store the root JSON value on success.
    1131  * @param   pErrInfo        Where to store extended error info. Optional.
    1132  */
    1133 static int rtJsonParse(PRTJSONTOKENIZER pTokenizer, PRTJSONVALINT *ppJsonVal,
    1134                        PRTERRINFO pErrInfo)
     1159 */
     1160static int rtJsonParse(PRTJSONTOKENIZER pTokenizer, PRTJSONVALINT *ppJsonVal)
    11351161{
    11361162    PRTJSONTOKEN pToken = NULL;
    11371163    int rc = rtJsonTokenizerGetToken(pTokenizer, &pToken);
    11381164    if (RT_SUCCESS(rc))
    1139         rc = rtJsonParseValue(pTokenizer, pToken, ppJsonVal, pErrInfo);
     1165        rc = rtJsonParseValue(pTokenizer, pToken, ppJsonVal);
    11401166
    11411167    return rc;
     
    11981224}
    11991225
    1200 RTDECL(int) RTJsonParseFromBuf(PRTJSONVAL phJsonVal, const uint8_t *pbBuf, size_t cbBuf,
    1201                                PRTERRINFO pErrInfo)
     1226RTDECL(int) RTJsonParseFromBuf(PRTJSONVAL phJsonVal, const uint8_t *pbBuf, size_t cbBuf, PRTERRINFO pErrInfo)
    12021227{
    12031228    AssertPtrReturn(phJsonVal, VERR_INVALID_POINTER);
     
    12101235    Args.u.pbBuf = pbBuf;
    12111236
    1212     int rc = rtJsonTokenizerInit(&Tokenizer, rtJsonTokenizerParseFromBuf, &Args);
     1237    int rc = rtJsonTokenizerInit(&Tokenizer, rtJsonTokenizerParseFromBuf, &Args, pErrInfo);
    12131238    if (RT_SUCCESS(rc))
    12141239    {
    1215         rc = rtJsonParse(&Tokenizer, phJsonVal, pErrInfo);
     1240        rc = rtJsonParse(&Tokenizer, phJsonVal);
    12161241        rtJsonTokenizerDestroy(&Tokenizer);
    12171242    }
     
    12301255     *        forces with RTJsonParseFromBuf. */
    12311256    RTJSONTOKENIZER Tokenizer;
    1232     int rc = rtJsonTokenizerInit(&Tokenizer, rtJsonTokenizerParseFromString, (void *)pszStr);
     1257    int rc = rtJsonTokenizerInit(&Tokenizer, rtJsonTokenizerParseFromString, (void *)pszStr, pErrInfo);
    12331258    if (RT_SUCCESS(rc))
    12341259    {
    1235         rc = rtJsonParse(&Tokenizer, phJsonVal, pErrInfo);
     1260        rc = rtJsonParse(&Tokenizer, phJsonVal);
    12361261        rtJsonTokenizerDestroy(&Tokenizer);
    12371262    }
     
    12541279        RTJSONTOKENIZER Tokenizer;
    12551280
    1256         rc = rtJsonTokenizerInit(&Tokenizer, rtJsonTokenizerParseFromFile, &Args);
     1281        rc = rtJsonTokenizerInit(&Tokenizer, rtJsonTokenizerParseFromFile, &Args, pErrInfo);
    12571282        if (RT_SUCCESS(rc))
    12581283        {
    1259             rc = rtJsonParse(&Tokenizer, phJsonVal, pErrInfo);
     1284            rc = rtJsonParse(&Tokenizer, phJsonVal);
    12601285            rtJsonTokenizerDestroy(&Tokenizer);
    12611286        }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette