* Copyright (C) 2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include "functionalext.h"
const size_t ERROR_LEN = -1;
const int STR_LEN = 1024;
const int TEST_NUM = 123;
const double TEST_DOUBLE = 45.67;
const int FORTITY_LEVEL = 2;
* @tc.name: __fprintf_chk_0100
* @tc.desc: Verify __fprintf_chk and fp is NULL will return -1.
* @tc.level: level 0.
*/
void __fprintf_chk_0100(void)
{
const char* data = "Hello, this is a test.\n";
pid_t pid = fork();
if (pid < 0) {
t_error("fork failed\n");
} else if (pid == 0) {
(void)__fprintf_chk(NULL, FORTITY_LEVEL, "%s", data);
} else {
int status;
waitpid(pid, &status, WUNTRACED);
EXPECT_TRUE("__fprintf_chk_0100", WIFSIGNALED(status));
EXPECT_EQ("__fprintf_chk_0100", WTERMSIG(status), SIGABRT);
}
}
* @tc.name: __fprintf_chk_0200
* @tc.desc: Verify __fprintf_chk and format is NULL will return -1.
* @tc.level: level 0.
*/
void __fprintf_chk_0200(void)
{
const char* data = "Hello, this is a test.\n";
ssize_t result = __fprintf_chk(stdout, FORTITY_LEVEL, NULL, data);
EXPECT_EQ("__fprintf_chk_0200", result, ERROR_LEN);
EXPECT_EQ("__fprintf_chk_0200", errno, EINVAL);
}
* @tc.name: __fprintf_chk_0300
* @tc.desc: Verify __fprintf_chk and fopen("w") process success.
* @tc.level: level 0.
*/
void __fprintf_chk_0300(void)
{
char str[] = "这是一个测试.";
int len = 0;
FILE *fptr = fopen("tempory_testfprintfchk.txt", "w");
if (fptr != NULL) {
len = __fprintf_chk(fptr, FORTITY_LEVEL, "%s", str);
fclose(fptr);
}
EXPECT_EQ("__fprintf_chk_0300", len, strlen(str));
}
* @tc.name: __fprintf_chk_0400
* @tc.desc: Verify __fprintf_chk and fopen("r") and return -1.
* @tc.level: level 2.
*/
void __fprintf_chk_0400(void)
{
char str[] = "Hello, this is a test.\n";
size_t len = 0;
FILE *fptr = fopen("tempory_testfprintfchk.txt", "r");
if (fptr != NULL) {
len = __fprintf_chk(fptr, FORTITY_LEVEL, "%s", str);
fclose(fptr);
}
EXPECT_EQ("__fprintf_chk_0400", len, ERROR_LEN);
EXPECT_EQ("__fprintf_chk_0400", errno, EBADF);
(void)remove("tempory_testfprintfchk.txt");
}
* @tc.name: __fprintf_chk_0500
* @tc.desc: Verify __fprintf_chk and stdout process success.
* @tc.level: level 0.
*/
void __fprintf_chk_0500(void)
{
char str[] = "Hello, this is a test.\n";
size_t len = __fprintf_chk(stdout, FORTITY_LEVEL, "%s", str);
EXPECT_EQ("__fprintf_chk_0500", len, strlen(str));
}
* @tc.name: __fprintf_chk_0600
* @tc.desc: Verify __fprintf_chk and stderr process success.
* @tc.level: level 0.
*/
void __fprintf_chk_0600(void)
{
char str[] = "Hello, this is a test.\n";
size_t len = __fprintf_chk(stderr, FORTITY_LEVEL, "%s", str);
EXPECT_EQ("__fprintf_chk_0600", len, strlen(str));
}
* @tc.name: __fprintf_chk_0700
* @tc.desc: Verify __fprintf_chk with multiple format specifiers.
* @tc.level: level 0.
*/
void __fprintf_chk_0700(void)
{
char str[] = "Test";
size_t len = 0;
FILE *fptr = fopen("tempory_testfprintfchk.txt", "w");
if (fptr != NULL) {
len = __fprintf_chk(fptr, FORTITY_LEVEL, "String: %s, Int: %d, Double: %.2f", str, TEST_NUM, TEST_DOUBLE);
fclose(fptr);
}
int expected_len = strlen("String: Test, Int: 123, Double: 45.67");
EXPECT_EQ("__fprintf_chk_0700", len, expected_len);
(void)remove("tempory_testfprintfchk.txt");
}
* @tc.name: __fprintf_chk_0800
* @tc.desc: Verify __fprintf_chk with append mode.
* @tc.level: level 0.
*/
void __fprintf_chk_0800(void)
{
char str1[] = "First line\n";
char str2[] = "Second line\n";
FILE *fptr = fopen("tempory_testfprintfchk.txt", "w");
if (fptr != NULL) {
__fprintf_chk(fptr, FORTITY_LEVEL, "%s", str1);
fclose(fptr);
}
fptr = fopen("tempory_testfprintfchk.txt", "a");
size_t len = 0;
if (fptr != NULL) {
len = __fprintf_chk(fptr, FORTITY_LEVEL, "%s", str2);
fclose(fptr);
}
EXPECT_EQ("__fprintf_chk_0800", len, strlen(str2));
(void)remove("tempory_testfprintfchk.txt");
}
* @tc.name: __fprintf_chk_0900
* @tc.desc: Verify __fprintf_chk with large string.
* @tc.level: level 0.
*/
void __fprintf_chk_0900(void)
{
char large_str[STR_LEN];
memset(large_str, 'A', sizeof(large_str) - 1);
large_str[sizeof(large_str) - 1] = '\0';
size_t len = 0;
FILE *fptr = fopen("tempory_testfprintfchk.txt", "w");
if (fptr != NULL) {
len = __fprintf_chk(fptr, FORTITY_LEVEL, "%s", large_str);
fclose(fptr);
}
EXPECT_EQ("__fprintf_chk_0900", len, strlen(large_str));
(void)remove("tempory_testfprintfchk.txt");
}
* @tc.name: __fprintf_chk_1000
* @tc.desc: Verify __fprintf_chk with special characters.
* @tc.level: level 0.
*/
void __fprintf_chk_1000(void)
{
char str[] = "Special chars: \t\n\r\\\"\'";
size_t len = 0;
FILE *fptr = fopen("tempory_testfprintfchk.txt", "w");
if (fptr != NULL) {
len = __fprintf_chk(fptr, FORTITY_LEVEL, "%s", str);
fclose(fptr);
}
EXPECT_EQ("__fprintf_chk_1000", len, strlen(str));
(void)remove("tempory_testfprintfchk.txt");
}
* @tc.name: __fprintf_chk_1100
* @tc.desc: Basic functionality test.
* @tc.level: level 0.
*/
void __fprintf_chk_1100(void)
{
int ret = 0;
ret = __fprintf_chk(stdout, 0, "%d, %.2f, %s\n", 123, 3.1415, "Hello __fprintf_chk");
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(stdout, 1, "%d, %.2f, %s\n", 123, 3.1415, "Hello __fprintf_chk");
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(stderr, 0, "%d\n", 999);
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(stderr, 1, "%d\n", 999);
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(stdout, 0, "\\n \\t \"%s\"\n", "");
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(stdout, 1, "\\n \\t \"%s\"\n", "");
EXPECT_TRUE(__FUNCTION__, ret > 0);
}
* @tc.name: __fprintf_chk_1200
* @tc.desc: File stream output.
* @tc.level: level 0.
*/
void __fprintf_chk_1200(void)
{
const char *filename = "tempory_testfprintfchk.txt";
FILE *fp = NULL;
int ret = 0;
fp = fopen(filename, "w");
EXPECT_TRUE(__FUNCTION__, fp != NULL);
ret = __fprintf_chk(fp, 1, "__fprintf_chk test\n");
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(fp, 1, "%d, %ld, %s\n", 1, 123456789L, "true");
EXPECT_TRUE(__FUNCTION__, ret > 0);
(void)fclose(fp);
fp = NULL;
fp = fopen(filename, "r");
EXPECT_TRUE(__FUNCTION__, fp != NULL);
char buf[256] = {0};
char expected_content[256] = "__fprintf_chk test\n1, 123456789, true\n";
(void)fread(buf, 1, sizeof(buf) - 1, fp);
EXPECT_STREQ(__FUNCTION__, expected_content, buf);
(void)fclose(fp);
fp = NULL;
(void)remove(filename);
}
* @tc.name: __fprintf_chk_1300
* @tc.desc: Boundary scenario testing.
* @tc.level: level 0.
*/
void __fprintf_chk_1300(void)
{
int ret = 0;
ret = __fprintf_chk(stdout, 0, "%d\n", 123);
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(stdout, 1, "%d\n", 123);
EXPECT_TRUE(__FUNCTION__, ret > 0);
ret = __fprintf_chk(stdout, 0, "");
EXPECT_TRUE(__FUNCTION__, ret == 0);
ret = __fprintf_chk(stdout, 1, "");
EXPECT_TRUE(__FUNCTION__, ret == 0);
}
void* mt_worker(void* arg)
{
__fprintf_chk_0500();
return NULL;
}
* @tc.name : __fprintf_chk_1400
* @tc.desc : Stability Testing.
* @tc.level : Level 0
*/
void __fprintf_chk_1400(void)
{
const int N = 8;
pthread_t tids[N];
for (int i = 0; i < N; i++) {
EXPECT_EQ(__FUNCTION__, pthread_create(&tids[i], NULL, mt_worker, NULL), 0);
}
for (int i = 0; i < N; i++) {
pthread_join(tids[i], NULL);
}
}
int main(void)
{
__fprintf_chk_0100();
__fprintf_chk_0200();
__fprintf_chk_0300();
__fprintf_chk_0400();
__fprintf_chk_0500();
__fprintf_chk_0600();
__fprintf_chk_0700();
__fprintf_chk_0800();
__fprintf_chk_0900();
__fprintf_chk_1000();
__fprintf_chk_1100();
__fprintf_chk_1200();
__fprintf_chk_1300();
__fprintf_chk_1400();
return t_status;
}