如何在C语言字符串数组指定位置添加双引号以格式化PEM证书
问题排查
你的代码存在以下几个致命错误,直接导致ESP内核崩溃:
- 长度计算错误:
int newUnformattedLen = unformatterPem + 500;这里unformatterPem是输入字符串的指针,你误把指针地址加500当作新字符串长度,导致newKey数组长度完全非法,直接触发内存越界。正确的应该是用计算好的原字符串长度unformattedPemLen + 500。 - 字符串比较函数使用错误:
strcmp(key[keyI],"\n")==0是完全错误的用法,strcmp接收的是两个字符串首地址,你传入的key[keyI]是单个字符值,等于把字符的ASCII码当作内存地址去访问,直接触发非法内存访问崩溃。判断单个字符是否为换行直接用key[keyI] == '\n'即可。 - 返回栈内存地址:
newKey是函数内部定义的局部数组,分配在栈上,函数执行完成后栈空间会被系统回收,返回的newKey地址是野指针,后续访问直接崩溃。需要用malloc动态分配堆内存存储结果,堆内存不会随函数结束自动回收。 - 格式逻辑缺失:你当前只在换行符后加了双引号,缺少下一行开头的双引号,和你期望的每行首尾都有双引号的格式不符。
- 缺少字符串结束符:构造完的
newKey没有手动追加\0结束符,作为字符串打印、使用时会越界读取后续内存。
修复后代码
#include <string.h> #include <stdlib.h> #include "esp_log.h" static const char *MQTT_TAG = "mqtt"; char *Format(char *unformattedPem) { int unformattedPemLen = strlen(unformattedPem); // 动态分配内存,预留足够的双引号和结束符空间 int newBufLen = unformattedPemLen * 2 + 10; char *newKey = malloc(newBufLen); if (newKey == NULL) { ESP_LOGE(MQTT_TAG, "malloc failed"); return NULL; } int keyI = 0, keyJ = 0; // 首行开头加双引号 newKey[keyJ++] = '"'; while (keyI < unformattedPemLen) { if (unformattedPem[keyI] == '\n') { // 换行先复制到新串 newKey[keyJ++] = unformattedPem[keyI++]; // 行尾加双引号 newKey[keyJ++] = '"'; // 下一行开头加双引号,避免给最后一行末尾多余添加 if (keyI < unformattedPemLen) { newKey[keyJ++] = '"'; } } else { newKey[keyJ++] = unformattedPem[keyI++]; } } // 末尾补字符串结束符 newKey[keyJ] = '\0'; ESP_LOGI(MQTT_TAG, "Formatted key: \n%s", newKey); return newKey; }
使用注意
调用方使用完返回的格式化字符串后,需要手动调用free()释放内存,避免内存泄漏:
char *pkey = "-----BEGIN CERTIFICATE-----\nMIIGCTCCA/GgAwIBAgIUB2IexWz8meqWx0ihY6f623xszc0wDQYJKoZIhvcNAQEL\nBQAwgYsxCzAJBgNVBAYTARtaW5AZmlyZXdpcmVzLmlu\nMiBlkN7eNDHQnjHcyuyTS2SVGddsuEEqQe3BA3SgOUvwtOT3DNXDkfM8yV2RgZxZh\nTFSaoxLw4Y1N2lGoAeHeKpdk1IuyqTz+3OM4AWLp6geDypp/Ymt\n2r9E1hvjg9KV3UGmIQ==\n-----END CERTIFICATE-----"; char *newKey = Format(pkey); // 使用newKey做后续操作 // ...... // 使用完释放内存 free(newKey);
内容的提问来源于stack exchange,提问作者horsemann07
相关产品推荐
相关产品推荐

