= js_InflateString(cx, *messagep, strlen(*messagep));
= js_InflateString(cx, *messagep, &len);
js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,                        void *userRef, const uintN errorNumber,                        char **messagep, JSErrorReport *reportp,                        JSBool *warningp, JSBool charArgs, va_list ap){    const JSErrorFormatString *efs;    int i;    int argCount;    *warningp = JSREPORT_IS_WARNING(reportp->flags);    if (*warningp && JS_HAS_WERROR_OPTION(cx)) {        reportp->flags &= ~JSREPORT_WARNING;        *warningp = JS_FALSE;    }    *messagep = NULL;    if (callback) {        efs = callback(userRef, NULL, errorNumber);        if (efs) {            size_t totalArgsLength = 0;            size_t argLengths[10]; /* only {0} thru {9} supported */            argCount = efs->argCount;            JS_ASSERT(argCount <= 10);            if (argCount > 0) {                /*                 * Gather the arguments into an array, and accumulate                 * their sizes. We allocate 1 more than necessary and                 * null it out to act as the caboose when we free the                 * pointers later.                 */                reportp->messageArgs = (const jschar **)                    JS_malloc(cx, sizeof(jschar *) * (argCount + 1));                if (!reportp->messageArgs)                    return JS_FALSE;                reportp->messageArgs[argCount] = NULL;                for (i = 0; i < argCount; i++) {                    if (charArgs) {                        char *charArg = va_arg(ap, char *);                        reportp->messageArgs[i]                            = js_InflateString(cx, charArg, strlen(charArg));                        if (!reportp->messageArgs[i])                            goto error;                    }                    else                        reportp->messageArgs[i] = va_arg(ap, jschar *);                    argLengths[i] = js_strlen(reportp->messageArgs[i]);                    totalArgsLength += argLengths[i];                }                /* NULL-terminate for easy copying. */                reportp->messageArgs[i] = NULL;            }            /*             * Parse the error format, substituting the argument X             * for {X} in the format.             */            if (argCount > 0) {                if (efs->format) {                    const char *fmt;                    const jschar *arg;                    jschar *out;                    int expandedArgs = 0;                    size_t expandedLength                        = strlen(efs->format)                            - (3 * argCount) /* exclude the {n} */                            + totalArgsLength;                    /*                     * Note - the above calculation assumes that each argument                     * is used once and only once in the expansion !!!                     */                    reportp->ucmessage = out = (jschar *)                        JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));                    if (!out)                        goto error;                    fmt = efs->format;                    while (*fmt) {                        if (*fmt == '{') {                            if (isdigit(fmt[1])) {                                int d = JS7_UNDEC(fmt[1]);                                JS_ASSERT(d < argCount);                                arg = reportp->messageArgs[d];                                js_strncpy(out, arg, argLengths[d]);                                out += argLengths[d];                                fmt += 3;                                expandedArgs++;                                continue;                            }                        }                        /*                         * is this kosher?                         */                        *out++ = (unsigned char)(*fmt++);                    }                    JS_ASSERT(expandedArgs == argCount);                    *out = 0;                    *messagep =                        js_DeflateString(cx, reportp->ucmessage,                                         (size_t)(out - reportp->ucmessage));                    if (!*messagep)                        goto error;                }            } else {                /*                 * Zero arguments: the format string (if it exists) is the                 * entire message.                 */                if (efs->format) {                    *messagep = JS_strdup(cx, efs->format);                    if (!*messagep)                        goto error;                    reportp->ucmessage                        = js_InflateString(cx, *messagep, strlen(*messagep));                    if (!reportp->ucmessage)                        goto error;                }            }        }    }    if (*messagep == NULL) {        /* where's the right place for this ??? */        const char *defaultErrorMessage            = "No error message available for error number %d";        size_t nbytes = strlen(defaultErrorMessage) + 16;        *messagep = (char *)JS_malloc(cx, nbytes);        if (!*messagep)            goto error;        JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);    }    return JS_TRUE;error:    if (reportp->messageArgs) {        i = 0;        while (reportp->messageArgs[i])            JS_free(cx, (void *)reportp->messageArgs[i++]);        JS_free(cx, (void *)reportp->messageArgs);        reportp->messageArgs = NULL;    }    if (reportp->ucmessage) {        JS_free(cx, (void *)reportp->ucmessage);        reportp->ucmessage = NULL;    }    if (*messagep) {        JS_free(cx, (void *)*messagep);        *messagep = NULL;    }    return JS_FALSE;}