13d58139fSopenharmony_ci/*
23d58139fSopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.
33d58139fSopenharmony_ci * Licensed under Mulan PSL v2.
43d58139fSopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2.
53d58139fSopenharmony_ci * You may obtain a copy of Mulan PSL v2 at:
63d58139fSopenharmony_ci *          http://license.coscl.org.cn/MulanPSL2
73d58139fSopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
83d58139fSopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
93d58139fSopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
103d58139fSopenharmony_ci * See the Mulan PSL v2 for more details.
113d58139fSopenharmony_ci * Description: By defining corresponding macro for ANSI string and including "output.inl",
123d58139fSopenharmony_ci *              this file generates real underlying function used by printf family API.
133d58139fSopenharmony_ci * Create: 2014-02-25
143d58139fSopenharmony_ci */
153d58139fSopenharmony_ci
163d58139fSopenharmony_ci#define SECUREC_FORMAT_OUTPUT_INPUT 1
173d58139fSopenharmony_ci
183d58139fSopenharmony_ci#ifdef SECUREC_FOR_WCHAR
193d58139fSopenharmony_ci#undef SECUREC_FOR_WCHAR
203d58139fSopenharmony_ci#endif
213d58139fSopenharmony_ci
223d58139fSopenharmony_ci#include "secureprintoutput.h"
233d58139fSopenharmony_ci#if SECUREC_WARP_OUTPUT
243d58139fSopenharmony_ci#define SECUREC_FORMAT_FLAG_TABLE_SIZE 128
253d58139fSopenharmony_ciSECUREC_INLINE const char *SecSkipKnownFlags(const char *format)
263d58139fSopenharmony_ci{
273d58139fSopenharmony_ci    static const unsigned char flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = {
283d58139fSopenharmony_ci        /*
293d58139fSopenharmony_ci         * Known flag is  "0123456789 +-#hlLwZzjqt*I$"
303d58139fSopenharmony_ci         */
313d58139fSopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323d58139fSopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333d58139fSopenharmony_ci        0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,
343d58139fSopenharmony_ci        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353d58139fSopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
363d58139fSopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
373d58139fSopenharmony_ci        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
383d58139fSopenharmony_ci        0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
393d58139fSopenharmony_ci    };
403d58139fSopenharmony_ci    const char *fmt = format;
413d58139fSopenharmony_ci    while (*fmt != '\0') {
423d58139fSopenharmony_ci        char fmtChar = *fmt;
433d58139fSopenharmony_ci        if ((unsigned char)fmtChar > 0x7f) { /* 0x7f is upper limit of format char value */
443d58139fSopenharmony_ci            break;
453d58139fSopenharmony_ci        }
463d58139fSopenharmony_ci        if (flagTable[(unsigned char)fmtChar] == 0) {
473d58139fSopenharmony_ci            break;
483d58139fSopenharmony_ci        }
493d58139fSopenharmony_ci        ++fmt;
503d58139fSopenharmony_ci    }
513d58139fSopenharmony_ci    return fmt;
523d58139fSopenharmony_ci}
533d58139fSopenharmony_ci
543d58139fSopenharmony_ciSECUREC_INLINE int SecFormatContainN(const char *format)
553d58139fSopenharmony_ci{
563d58139fSopenharmony_ci    const char *fmt = format;
573d58139fSopenharmony_ci    while (*fmt != '\0') {
583d58139fSopenharmony_ci        ++fmt;
593d58139fSopenharmony_ci        /* Skip normal char */
603d58139fSopenharmony_ci        if (*(fmt - 1) != '%') {
613d58139fSopenharmony_ci            continue;
623d58139fSopenharmony_ci        }
633d58139fSopenharmony_ci        /* Meet %% */
643d58139fSopenharmony_ci        if (*fmt == '%') {
653d58139fSopenharmony_ci            ++fmt; /* Point to  the character after the %. Correct handling %%xx */
663d58139fSopenharmony_ci            continue;
673d58139fSopenharmony_ci        }
683d58139fSopenharmony_ci        /* Now parse %..., fmt point to the character after the % */
693d58139fSopenharmony_ci        fmt = SecSkipKnownFlags(fmt);
703d58139fSopenharmony_ci        if (*fmt == 'n') {
713d58139fSopenharmony_ci            return 1;
723d58139fSopenharmony_ci        }
733d58139fSopenharmony_ci    }
743d58139fSopenharmony_ci    return 0;
753d58139fSopenharmony_ci}
763d58139fSopenharmony_ci/*
773d58139fSopenharmony_ci * Multi character formatted output implementation, the count include \0 character, must be greater than zero
783d58139fSopenharmony_ci */
793d58139fSopenharmony_ciint SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)
803d58139fSopenharmony_ci{
813d58139fSopenharmony_ci    int retVal;
823d58139fSopenharmony_ci    if (SecFormatContainN(format) != 0) {
833d58139fSopenharmony_ci        string[0] = '\0';
843d58139fSopenharmony_ci        return -1;
853d58139fSopenharmony_ci    }
863d58139fSopenharmony_ci    SECUREC_MASK_VSPRINTF_WARNING
873d58139fSopenharmony_ci    retVal = vsnprintf(string, count, format, argList);
883d58139fSopenharmony_ci    SECUREC_END_MASK_VSPRINTF_WARNING
893d58139fSopenharmony_ci    if (retVal >= (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */
903d58139fSopenharmony_ci        /* The buffer was too small; we return truncation */
913d58139fSopenharmony_ci        string[count - 1] = '\0';
923d58139fSopenharmony_ci        return SECUREC_PRINTF_TRUNCATE;
933d58139fSopenharmony_ci    }
943d58139fSopenharmony_ci    if (retVal < 0) {
953d58139fSopenharmony_ci        string[0] = '\0'; /* Empty the dest strDest */
963d58139fSopenharmony_ci        return -1;
973d58139fSopenharmony_ci    }
983d58139fSopenharmony_ci    return retVal;
993d58139fSopenharmony_ci}
1003d58139fSopenharmony_ci#else
1013d58139fSopenharmony_ci#if SECUREC_IN_KERNEL
1023d58139fSopenharmony_ci#include <linux/ctype.h>
1033d58139fSopenharmony_ci#endif
1043d58139fSopenharmony_ci
1053d58139fSopenharmony_ci#ifndef EOF
1063d58139fSopenharmony_ci#define EOF (-1)
1073d58139fSopenharmony_ci#endif
1083d58139fSopenharmony_ci
1093d58139fSopenharmony_ci#include "output.inl"
1103d58139fSopenharmony_ci
1113d58139fSopenharmony_ci#endif
1123d58139fSopenharmony_ci
113