无意中发现的strncmp()

在单片机开发的时候,项目需要用到了string.h中的STRNCMP()函数。

在调试的时候,发现strncmp()存在一个漏洞,当你指定长度大少的时候,更

函数在比较的小于指定长度的字符串(前面字符向相同情况下)一样输出相匹配。

例如: strncpy(string1,“123456”,6);当你输入:12345、123、1234等都

返回0,比较相同。


更改后:

u8 my_strncmp(u8 *string1,u8 *string2,size_t count)
{
u8 res,k=1;
    while(*string1!='\0'&&*string2!='\0'&&k<count)
    {
        k++;
    if(*string1==*string2)
    {
        string1++;
      string2++;     
    }
    else    break;
}
    res=*string1-*string2;
  return res;
}


今晚再补充

/*********************************************************************************** Copy right: hqyj Tech. Author: jiaoyue Date: 2023.07.01 Description: http请求处理 ***********************************************************************************/ #include <sys/types.h> #include <sys/socket.h> #include "custom_handle.h" #include <unistd.h> #include <signal.h> #include <semaphore.h> #include <stdbool.h> #define KB 1024 #define HTML_SIZE (64 * KB) extern pid_t pid_poll; extern bool flag; // 普通的文本回复需要增加html头部 #define HTML_HEAD "Content-Type: text/html\r\n" \ "Connection: close\r\n" extern char *p; static int handle_login(int sock, const char *input) { char reply_buf[HTML_SIZE] = {0}; char *uname = strstr(input, "username="); uname += strlen("username="); char *p = strstr(input, "password"); *(p - 1) = '\0'; printf("username = %s\n", uname); char *passwd = p + strlen("password="); printf("passwd = %s\n", passwd); if (strcmp(uname, "admin") == 0 && strcmp(passwd, "admin") == 0) { sprintf(reply_buf, "<script>localStorage.setItem('usr_user_name', '%s');</script>", uname); strcat(reply_buf, "<script>window.location.href = '/index.html';</script>"); send(sock, reply_buf, strlen(reply_buf), 0); } else { printf("web login failed\n"); //"用户名或密码错误"提示,chrome浏览器直接输送utf-8字符流乱码,没有找到太好解决方案,先过渡 char out[128] = {0xd3, 0xc3, 0xbb, 0xa7, 0xc3, 0xfb, 0xbb, 0xf2, 0xc3, 0xdc, 0xc2, 0xeb, 0xb4, 0xed, 0xce, 0xf3}; sprintf(reply_buf, "<script charset='gb2312'>alert('%s');</script>", out); strcat(reply_buf, "<script>window.location.href = '/login.html';</script>"); send(sock, reply_buf, strlen(reply_buf), 0); } return 0; } static int handle_add(int sock, const char *input) { int number1, number2; // input必须是"data1=1data2=6"类似的格式,注意前端过来的字符串会有双引号 sscanf(input, "\"data1=%ddata2=%d\"", &number1, &number2); printf("num1 = %d\n", number1); printf("num1 = %d\n", number2); char reply_buf[HTML_SIZE] = {0}; printf("num = %d\n", number1 + number2); sprintf(reply_buf, "%d", number1 + number2); printf("resp = %s\n", reply_buf); send(sock, reply_buf, strlen(reply_buf), 0); return 0; } static int handle_regDAQ(int sock, const char *input) { flag = false; int data_reg[4] = {}; char reply_buf[HTML_SIZE] = ""; kill(pid_poll, SIGUSR1); printf("85\n"); while (1) { if (flag) { printf("%s\n", p); printf("flag:%d\n", flag); sscanf(p, "Light Sensor:%d ; Accelerometer x:%d y:%d z:%d\n", &data_reg[0], &data_reg[1], &data_reg[2], &data_reg[3]); sprintf(reply_buf, "%d%d%d%d", data_reg[0], data_reg[1], data_reg[2], data_reg[3]); } break; } printf("resp = %s\n", reply_buf); send(sock, reply_buf, sizeof(reply_buf), 0); return 0; } static int handle_CTRL(int sock, const char *input) { int regno = 0, SRB = 0; char reply_buf[HTML_SIZE] = ""; sscanf(input, "registerno:%dSet/Reset Operations:%d", &regno, &SRB); printf("regno = %d SRB = %d", regno, SRB); printf("%s\n", p); if (regno == 0) { if (SRB == 0) printf("LED Lighting Deactivated\n"); else if (SRB == 1) printf("LED Lighting Activated\n"); } else if (regno == 1) { if (SRB == 0) printf("Buzzer Disengaged\n"); else if (SRB == 1) printf("Buzzer Engaged\n"); } sprintf(p, "ctrl: %d %d", regno, SRB); // kill(getpid(),SIGUSR1); send(sock, reply_buf, sizeof(reply_buf), 0); return 0; } /** * @brief 处理自定义请求,在这里添加进程通信 * @param input * @return */ int parse_and_process(int sock, const char *query_string, const char *input) { // query_string不一定能用的到 // 先处理登录操作 if (strstr(input, "username=") && strstr(input, "password=")) { return handle_login(sock, input); } // 处理求和请求 else if (strstr(input, "data1=") && strstr(input, "data2=")) { return handle_add(sock, input); } else if (strstr(input, "registers data acquisition")) { return handle_regDAQ(sock, input); } else if (strstr(input, "registerno:") && strstr(input, "Set/Reset Operations:")) { return handle_CTRL(sock, input); } else // 剩下的都是json请求,这个和协议有关了 { // 构建要回复的JSON数据 const char *json_response = "{\"message\": \"Hello, client!\"}"; // 发送HTTP响应给客户端 send(sock, json_response, strlen(json_response), 0); } return 0; } // 读光线传感器 -> 一个保持传感器、加速度传感器(x / y / z) -> 三个保持寄存器 // 控制led灯 -> 一个线圈传感器、蜂鸣器 -> 一个线圈传感器 /* Holding Registers -> HR Coil Registers -> CR LED Lighting -> LED Buzzer -> BZ Light Sensor -> LS Accelerometer -> ACC Data Acquisition -> DAQ Control -> CTRL */ #include <stdio.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <modbus.h> #include <pthread.h> #include <time.h> #include <string.h> #include <sys/types.h> #include <semaphore.h> #include <signal.h> #include <sys/types.h> #include <sys/ipc.h> #include <errno.h> #include <sys/ipc.h> #include <sys/shm.h> #define N 32 uint16_t data_recv[N] = {}; int num_regs = 0, addr_start = 0; pthread_t thread_ctrl, thread_acq; modbus_t *ctx = NULL; char *p = NULL; pid_t pid_self = 0, pid_webserver = 0; // sem_t sign_acq, sign_ctrl; void *DAQ_HR(void *arg) { while (1) { // sem_wait(&sign_acq); modbus_read_registers(ctx, 0, 4, data_recv); sleep(1); // printf("Light Sensor:%d ; Accelerometer x:%d y:%d z:%d\n", data_recv[0], data_recv[1], data_recv[2], data_recv[3]); // sem_post(&sign_ctrl); } pthread_exit(NULL); } void handle_daq(int sig) { if (sig == SIGUSR1) { sprintf(p, "Light Sensor:%d ; Accelerometer x:%d y:%d z:%d\n", data_recv[0], data_recv[1], data_recv[2], data_recv[3]); kill(pid_webserver, SIGUSR2); } } void *CTRL_CR(void *arg) { int dev_flag = 0, opt_flag = 0; while (1) { // sem_wait(&sign_ctrl); if (!strncmp(p, "ctrl", 4)) { printf("%s\n", p); sscanf(p, "ctrl: %d %d", &dev_flag, &opt_flag); modbus_write_bit(ctx, dev_flag, opt_flag); if (dev_flag == 0) { if (opt_flag == 0) printf("LED Lighting Deactivated\n"); else if (opt_flag == 1) printf("LED Lighting Activated\n"); } else if (dev_flag == 1) { if (opt_flag == 0) printf("Buzzer Disengaged\n"); else if (opt_flag == 1) printf("Buzzer Engaged\n"); } memset(p, 0, 64); } } pthread_exit(NULL); } int main(int argc, char const *argv[]) { // if (sem_init(&sign_ctrl, 0, 0) || sem_init(&sign_acq, 0, 1)) // { // perror("sem_init err"); // return -1; // } if (argc != 3) { printf("format:%s <ip> <slave id>\n", argv[0]); return -1; } key_t key1 = ftok("../key.c", 'a'); if (key1 < 0) // failure -> -1 { perror("ftok err"); return -1; } printf("ftok success\n"); int shmid = shmget(key1, 64, IPC_CREAT | IPC_EXCL | 0777); if (shmid < 0) { if (errno == EEXIST) shmid = shmget(key1, 64, 0777); else { perror("shmget err"); return -1; } } printf("shmget success\n"); p = (char *)shmat(shmid, NULL, 0); if (p == (void *)-1) { perror("shmat err"); return -1; } printf("shmat success\n"); ctx = modbus_new_tcp(argv[1], 502); if (ctx == NULL) { perror("modbus_new_tcp err"); return -1; } modbus_set_slave(ctx, atoi(argv[2])); if (modbus_connect(ctx) < 0) { perror("modbus_set_slave err"); return -1; } pid_t pid_self = getpid(); while (1) { if (strstr(p, "pid_webserver")) { sscanf(p, "pid_webserver:%d", &pid_webserver); memset(p, 0, 64); sprintf(p, "pid_poll:%d", pid_self); break; } } printf("pid_self = %d pid_webserver = %d\n", pid_self, pid_webserver); signal(SIGUSR1, handle_daq); signal(SIGUSR2, SIG_IGN); pthread_create(&thread_ctrl, NULL, CTRL_CR, NULL); pthread_create(&thread_acq, NULL, DAQ_HR, NULL); // sem_destroy(&sign_ctrl); // sem_destroy(&sign_acq); pthread_join(thread_acq, NULL); pthread_join(thread_ctrl, NULL); modbus_close(ctx); modbus_free(ctx); shmdt(p); shmctl(shmid, IPC_RMID, NULL); return 0; }#include "thttpd.h" #include <sys/types.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/ipc.h> #include <errno.h> #include <sys/ipc.h> #include <sys/shm.h> #include <signal.h> #include <semaphore.h> #include <stdbool.h> char *p = NULL; pid_t pid_self = 0, pid_poll = 0; bool flag; static void *msg_request(void *arg) { // 这里客户端描述符通过参数传进来了 int sock = (int)arg; // 一般情况下,线程终止后,其终止状态一直保留到其它线程调用pthread_join获取它的状态为止。 // 但是线程也可以被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态。 pthread_detach(pthread_self()); // handler_msg作为所有的请求处理入口 return (void *)handler_msg(sock); } void handler_get(int sig) { if (sig == SIGUSR2) flag = true; } int main(int argc, char *argv[]) { // 如果不传递端口,那么使用默认端口80 int port = 80; if (argc > 1) { port = atoi(argv[1]); } key_t key1 = ftok("../key.c", 'a'); if (key1 < 0) // failure -> -1 { perror("ftok err"); return -1; } printf("ftok success\n"); int shmid = shmget(key1, 64, IPC_CREAT | IPC_EXCL | 0777); if (shmid < 0) { if (errno == EEXIST) shmid = shmget(key1, 64, 0777); else { perror("shmget err"); return -1; } } printf("shmget success\n"); p = (char *)shmat(shmid, NULL, 0); if (p == (void *)-1) { perror("shmat err"); return -1; } printf("shmat success\n"); // 初始化服务器 int lis_sock = init_server(port); pid_t pid_self = getpid(); sprintf(p, "pid_webserver:%d", pid_self); while (1) { if (strstr(p, "pid_poll")) { sscanf(p, "pid_poll:%d", &pid_poll); memset(p, 0, 64); break; } } printf("pid_self = %d pid_poll = %d\n", pid_self, pid_poll); signal(SIGUSR2, handler_get); signal(SIGUSR1, SIG_IGN); while (1) { struct sockaddr_in peer; socklen_t len = sizeof(peer); int sock = accept(lis_sock, (struct sockaddr *)&peer, &len); if (sock < 0) { perror("accept failed"); continue; } // 每次接收一个链接后,会自动创建一个线程,这实际上就是线程服务器模型的应用 pthread_t tid; if (pthread_create(&tid, NULL, msg_request, (void *)sock) > 0) { perror("pthread_create failed"); close(sock); } } return 0; } 为什么当发送SIGUSR2信号后,flag的值不变
最新发布
08-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值