Esempio n. 1
0
/*
 * The arguments from ap need to be packaged up into an array and stored
 * into the report struct.
 *
 * The format string addressed by the error number may contain operands
 * identified by the format {N}, where N is a decimal digit. Each of these
 * is to be replaced by the Nth argument from the va_list. The complete
 * message is placed into reportp->ucmessage converted to a JSString.
 *
 * Returns true if the expansion succeeds (can fail if out of memory).
 */
JSBool
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;

    /* Most calls supply js_GetErrorMessage; if this is so, assume NULL. */
    if (!callback || callback == js_GetErrorMessage)
        efs = js_GetLocalizedErrorMessage(cx, userRef, NULL, errorNumber);
    else
        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 *);
                    size_t charArgLength = strlen(charArg);
                    reportp->messageArgs[i]
                        = js_InflateString(cx, charArg, &charArgLength);
                    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;
        }
Esempio n. 2
0
JSBool
js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
{
    char *message;
    jschar *ucmessage;
    size_t messagelen;
    JSStackFrame *fp;
    JSErrorReport report;
    JSBool warning;

    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
        return JS_TRUE;

    message = JS_vsmprintf(format, ap);
    if (!message)
        return JS_FALSE;
    messagelen = strlen(message);

    memset(&report, 0, sizeof (struct JSErrorReport));
    report.flags = flags;
    report.errorNumber = JSMSG_USER_DEFINED_ERROR;
    report.ucmessage = ucmessage = js_InflateString(cx, message, &messagelen);

    /* Find the top-most active script frame, for best line number blame. */
    for (fp = cx->fp; fp; fp = fp->down) {
        if (fp->regs) {
            report.filename = fp->script->filename;
            report.lineno = js_PCToLineNumber(cx, fp->script, fp->regs->pc);
            break;
        }
    }

    warning = JSREPORT_IS_WARNING(report.flags);
    if (warning && JS_HAS_WERROR_OPTION(cx)) {
        report.flags &= ~JSREPORT_WARNING;
        warning = JS_FALSE;
    }

    ReportError(cx, message, &report);
    free(message);
    JS_free(cx, ucmessage);
    return warning;
}
Esempio n. 3
0
JSBool
js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
{
    JSStackFrame *fp;
    JSErrorReport report, *reportp;
    char *last;
    JSBool warning;

    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
        return JS_TRUE;

    /* Find the top-most active script frame, for best line number blame. */
    for (fp = cx->fp; fp && (!fp->script || !fp->pc); fp = fp->down)
        continue;

    reportp = &report;
    memset(reportp, 0, sizeof (struct JSErrorReport));
    report.flags = flags;
    if (fp) {
        report.filename = fp->script->filename;
        report.lineno = js_PCToLineNumber(fp->script, fp->pc);
        /* XXX should fetch line somehow */
    }
    last = JS_vsmprintf(format, ap);
    if (!last)
        return JS_FALSE;

    ReportError(cx, last, reportp);
    free(last);

    warning = JSREPORT_IS_WARNING(reportp->flags);
    if (warning && JS_HAS_WERROR_OPTION(cx)) {
        reportp->flags &= ~JSREPORT_WARNING;
        warning = JS_FALSE;
    }
    return warning;
}
Esempio n. 4
0
JSBool
js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
{
    char *last;
    JSStackFrame *fp;
    JSErrorReport report;
    JSBool warning;

    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
        return JS_TRUE;

    last = JS_vsmprintf(format, ap);
    if (!last)
        return JS_FALSE;

    memset(&report, 0, sizeof (struct JSErrorReport));
    report.flags = flags;

    /* Find the top-most active script frame, for best line number blame. */
    for (fp = cx->fp; fp; fp = fp->down) {
        if (fp->script && fp->pc) {
            report.filename = fp->script->filename;
            report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
            break;
        }
    }

    warning = JSREPORT_IS_WARNING(report.flags);
    if (warning && JS_HAS_WERROR_OPTION(cx)) {
        report.flags &= ~JSREPORT_WARNING;
        warning = JS_FALSE;
    }

    ReportError(cx, last, &report);
    free(last);
    return warning;
}
Esempio n. 5
0
/*
 * The arguments from ap need to be packaged up into an array and stored
 * into the report struct.
 *
 * The format string addressed by the error number may contain operands
 * identified by the format {N}, where N is a decimal digit. Each of these
 * is to be replaced by the Nth argument from the va_list. The complete
 * message is placed into reportp->ucmessage converted to a JSString.
 *
 * Returns true if the expansion succeeds (can fail if out of memory).
 */
JSBool
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(expandedArgs < 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;
                }
            }
        }