c++ - 使用 MCU 在 C 中解析 HTTP 数据
问题描述
我正在尝试在基于 MCU 的项目中使用 C 解析从 GET / POST 请求中获得的数据。我必须提前说,我已经有一段时间没有使用 c 和 c++ 了,所以欢迎任何建议。
因此,到达 MCU 的数据具有以下标记:
HTTP/1.1
Authorization: Basic blablah
Content-Type: application/json
{
redLedBrightness:50,
redLedIsOn:true,
greenLedBrightness:70,
greenLedIsOn:false,
}
其中行的结尾分别由\r
和给出\n
。我的方法需要逐行处理,并搜索相应的键(例如Authorization
or redLedBrightness
)及其值(例如blahblah
or 50
)。我编写了以下代码,在我使用的编译器中似乎运行良好,但在 MCU 中却不行。
声明中似乎存在问题之一,*tempInDataP = *index;
因为如果我将其注释掉,MCU 就会停止挂起。当然我需要这条线,但我无法弄清楚问题出在哪里。我怀疑我使用的编译器没有显示所有错误。
这是代码的改编:
#include <iostream>
#include <string>
#include <cstring>
#define IN_DATA_SIZE 100
#define TEMP_IN_DATA_SIZE 10
using namespace std;
char mock[] = "Authentication:YERL90,\r\nredLedBri:400,\r\nredLedOn:true\r\n";
char * mockP = mock;
char inData[IN_DATA_SIZE];
char * inDataP = inData;
char tempInData[TEMP_IN_DATA_SIZE];
char * tempInDataP = tempInData;
const char * auth = "YERL90";
bool isAuthenticated = false;
void printBuffer(char * buf) {
for (char *p = buf; *p; p++) {
cout << *p;
}
}
void resetBuffer(char * buf, int _size)
{
memset(buf, 0, _size);
}
/**
* Returns true if keyWord exists and update the variable tempInData
* with the response / value
*/
bool parseResponse(char * res, const char * keyWord, int dataShift ) {
cout << "\nParsing:" << res << endl;
char * index;
// Reset temp in data buffer and its pointer
resetBuffer(tempInData, TEMP_IN_DATA_SIZE);
tempInDataP = &tempInData[0];
// Search for a member /keyword inside the response
index = strstr(res, keyWord);
if (index) {
// Keyword exists in the response
// Move the index to the beginning of the value (key:value)
index = index + strlen(keyWord) + dataShift;
while ((*index != '\r') && (*index != ',')) {
*tempInDataP = *index;
tempInDataP++;
index++;
}
// Terminate the string with a null
*tempInDataP = '\0';
return true;
} else {
cout << "-bul" << endl;
//Object was not found
return false;
}
}
bool checkAuth(const char * _auth) {
if (strcmp (auth, _auth) == 0)
return true;
else
return false;
}
int main()
{
while(*mockP) {
// Simulating, reading data from the channel
*inDataP=*mockP;
//Parsing line by line
if (*inDataP == '\n') {
//Check for authentication if not done yet
if(!isAuthenticated) {
cout << "Authenticating ..." << endl;
if(parseResponse(inData, "Authentication", 1)) {
cout << "Key exists ..." << endl;
if(checkAuth(tempInData)) {
cout << "Correct Password" << endl;
isAuthenticated = true;
} else {
cout << "Password Invalid" << endl;
// Prepare headers
// Send response with unauthorized access
// stop connection
break;
}
} else {
cout << "Data not found" << endl;
}
} else {
// User is logged in
cout << "User is logged in" << endl;
if(parseResponse(inData, "redLedBri", 1)) {
cout << "Data exists:" << tempInData << endl;
// update local variables
} else {
cout << "Data not found" << endl;
}
}
resetBuffer(inData, IN_DATA_SIZE);
inDataP = &inData[0];
}
else {
inDataP++;
}
mockP++;
}
//close connection and log the user out
return 0;
}
我对其他替代方案持开放态度,因为根据发送到 MCU 的 JSON 文件,此实现似乎有点麻烦。
解决方案
我看到潜在的缓冲区溢出。你太相信你的意见了。您假设它将以 '\r' 或 ',' 字符结尾,如果不是,那么您将超出数组的边界并访问任意内存。
至少,为每个数组指针传递最大长度,并在每次循环迭代中检查您永远不会访问数组最后地址之外的元素。
推荐阅读
- php - 语言外观未检测到应用程序语言更改
- javascript - 反应材料ui文本字段(类型=数字)验证10个字符是否存在
- php - 自定义帖子类型 wordpress 的热门帖子
- regex - 通过 .htaccess 重定向我的旧网址不起作用
- asp.net-core - 如何使用 Sustainsys Saml2 从 Idp 发起的登录中检索声明?
- mysql - 如何使用 sql 或 eloquent 使用 group by 和 joins?
- css-animations - 将 Clippath CSS 关键帧动画转置为animejs 动画
- processing - 加工——倒车翻跟头
- javascript - 下拉禁用功能无法正常工作
- c - 如何使用 GCC 编译器和带有 -o 的 .o 文件正确编译多个文件?