Skip to content

Commit 0d035d0

Browse files
authored
replace cjson with jsmn
Signed-off-by: reda ghouzraf <98324229+rghouzra@users.noreply.github.com>
1 parent fdd5445 commit 0d035d0

File tree

1 file changed

+127
-55
lines changed

1 file changed

+127
-55
lines changed

plugins/out_oracle_log_analytics/oci_logan_conf.c

Lines changed: 127 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,58 +1005,92 @@ static flb_sds_t clean_token_string(flb_sds_t input)
10051005
return input;
10061006
}
10071007

1008-
10091008
static int parse_federation_response(flb_sds_t response,
10101009
struct oci_security_token *token)
10111010
{
1012-
cJSON *json = NULL;
1013-
cJSON *token_item = NULL;
1011+
jsmn_parser parser;
1012+
jsmntok_t *tokens;
1013+
int tok_size = 32;
1014+
int ret, i;
1015+
char *key;
1016+
char *val;
1017+
int key_len;
1018+
int val_len;
10141019

10151020
if (!response || !token) {
10161021
return -1;
10171022
}
10181023

1019-
json = cJSON_Parse(response);
1020-
if (!json) {
1021-
return -1;
1022-
}
1024+
jsmn_init(&parser);
10231025

1024-
token_item = cJSON_GetObjectItem(json, "token");
1025-
if (!token_item || !cJSON_IsString(token_item)) {
1026-
cJSON_Delete(json);
1026+
tokens = flb_calloc(1, sizeof(jsmntok_t) * tok_size);
1027+
if (!tokens) {
10271028
return -1;
10281029
}
10291030

1030-
const char *token_str = cJSON_GetStringValue(token_item);
1031-
if (!token_str) {
1032-
cJSON_Delete(json);
1033-
return -1;
1034-
}
1031+
ret =
1032+
jsmn_parse(&parser, response, flb_sds_len(response), tokens,
1033+
tok_size);
10351034

1036-
flb_sds_t raw_token = flb_sds_create(token_str);
1037-
if (!raw_token) {
1038-
cJSON_Delete(json);
1035+
if (ret == JSMN_ERROR_INVAL || ret == JSMN_ERROR_PART) {
1036+
flb_free(tokens);
10391037
return -1;
10401038
}
1039+
tok_size = ret;
1040+
for (i = 1; i < tok_size; i++) {
1041+
if (tokens[i].type != JSMN_STRING) {
1042+
continue;
1043+
}
10411044

1042-
if (!clean_token_string(raw_token)) {
1043-
flb_sds_destroy(raw_token);
1044-
cJSON_Delete(json);
1045-
return -1;
1046-
}
1045+
key = response + tokens[i].start;
1046+
key_len = tokens[i].end - tokens[i].start;
1047+
1048+
if (key_len == 5 && strncmp(key, "token", 5) == 0) {
1049+
i++;
1050+
if (i >= tok_size || tokens[i].type != JSMN_STRING) {
1051+
flb_free(tokens);
1052+
return -1;
1053+
}
1054+
1055+
val = response + tokens[i].start;
1056+
val_len = tokens[i].end - tokens[i].start;
10471057

1048-
if (token) {
1049-
flb_sds_destroy(token->token);
1058+
flb_sds_t raw_token = flb_sds_create_len(val, val_len);
1059+
if (!raw_token) {
1060+
flb_free(tokens);
1061+
return -1;
1062+
}
1063+
1064+
if (!clean_token_string(raw_token)) {
1065+
flb_sds_destroy(raw_token);
1066+
flb_free(tokens);
1067+
return -1;
1068+
}
1069+
1070+
if (token->token) {
1071+
flb_sds_destroy(token->token);
1072+
}
1073+
token->token = raw_token;
1074+
1075+
flb_free(tokens);
1076+
return 0;
1077+
}
10501078
}
1051-
token->token = raw_token;
10521079

1053-
cJSON_Delete(json);
1054-
return 0;
1080+
flb_free(tokens);
1081+
return -1;
10551082
}
10561083

10571084
// extract jwt and its expiration time
10581085
static int decode_jwt_and_set_expires(struct flb_oci_logan *ctx)
10591086
{
1087+
jsmn_parser parser;
1088+
jsmntok_t *tokens;
1089+
int tok_size = 32;
1090+
int ret, i;
1091+
char *key;
1092+
int key_len;
1093+
10601094
if (!ctx || !ctx->security_token.token) {
10611095
flb_plg_error(ctx->ins, "Invalid context or token");
10621096
return -1;
@@ -1080,11 +1114,11 @@ static int decode_jwt_and_set_expires(struct flb_oci_logan *ctx)
10801114
memcpy(payload_b64url, dot1 + 1, payload_b64url_len);
10811115
payload_b64url[payload_b64url_len] = '\0';
10821116

1083-
for (int i = 0; i < payload_b64url_len; i++) {
1084-
if (payload_b64url[i] == '-')
1085-
payload_b64url[i] = '+';
1086-
else if (payload_b64url[i] == '_')
1087-
payload_b64url[i] = '/';
1117+
for (int j = 0; j < payload_b64url_len; j++) {
1118+
if (payload_b64url[j] == '-')
1119+
payload_b64url[j] = '+';
1120+
else if (payload_b64url[j] == '_')
1121+
payload_b64url[j] = '/';
10881122
}
10891123

10901124
int padding = (4 - (payload_b64url_len % 4)) % 4;
@@ -1107,10 +1141,9 @@ static int decode_jwt_and_set_expires(struct flb_oci_logan *ctx)
11071141
return -1;
11081142
}
11091143

1110-
int ret =
1111-
flb_base64_decode((unsigned char *) decoded_payload, decoded_len,
1112-
&decoded_len, (unsigned char *) payload_b64,
1113-
b64_len);
1144+
ret = flb_base64_decode((unsigned char *) decoded_payload, decoded_len,
1145+
&decoded_len, (unsigned char *) payload_b64,
1146+
b64_len);
11141147
if (ret != 0) {
11151148
flb_plg_error(ctx->ins, "Base64 decode failed");
11161149
flb_free(payload_b64url);
@@ -1120,40 +1153,79 @@ static int decode_jwt_and_set_expires(struct flb_oci_logan *ctx)
11201153
}
11211154

11221155
decoded_payload[decoded_len] = '\0';
1123-
cJSON *json = cJSON_Parse(decoded_payload);
1124-
if (json == NULL) {
1125-
const char *error_ptr = cJSON_GetErrorPtr();
1126-
if (error_ptr != NULL) {
1127-
flb_plg_error(ctx->ins, "JSON parse error before: %s", error_ptr);
1128-
}
1129-
else {
1130-
flb_plg_error(ctx->ins, "JSON parse error");
1131-
}
1156+
1157+
jsmn_init(&parser);
1158+
1159+
tokens = flb_calloc(1, sizeof(jsmntok_t) * tok_size);
1160+
if (!tokens) {
11321161
flb_free(payload_b64url);
11331162
flb_free(payload_b64);
11341163
flb_free(decoded_payload);
11351164
return -1;
11361165
}
11371166

1138-
cJSON *exp_item = cJSON_GetObjectItem(json, "exp");
1139-
if (!exp_item || !cJSON_IsNumber(exp_item)) {
1140-
flb_plg_error(ctx->ins, "Missing or invalid 'exp' in JWT");
1141-
cJSON_Delete(json);
1167+
ret = jsmn_parse(&parser, decoded_payload, decoded_len, tokens, tok_size);
1168+
1169+
if (ret == JSMN_ERROR_INVAL || ret == JSMN_ERROR_PART) {
1170+
flb_plg_error(ctx->ins, "JSON parse error");
1171+
flb_free(tokens);
11421172
flb_free(payload_b64url);
11431173
flb_free(payload_b64);
11441174
flb_free(decoded_payload);
11451175
return -1;
11461176
}
11471177

1148-
time_t exp_value = (time_t) exp_item->valuedouble;
1149-
char *json_str = cJSON_Print(json);
1150-
if (json_str) {
1151-
flb_free(json_str);
1178+
tok_size = ret;
1179+
1180+
// Find "exp" key
1181+
time_t exp_value = 0;
1182+
for (i = 1; i < tok_size; i++) {
1183+
if (tokens[i].type != JSMN_STRING) {
1184+
continue;
1185+
}
1186+
1187+
key = decoded_payload + tokens[i].start;
1188+
key_len = tokens[i].end - tokens[i].start;
1189+
1190+
if (key_len == 3 && strncmp(key, "exp", 3) == 0) {
1191+
i++;
1192+
if (i >= tok_size || tokens[i].type != JSMN_PRIMITIVE) {
1193+
flb_plg_error(ctx->ins, "Missing or invalid 'exp' in JWT");
1194+
flb_free(tokens);
1195+
flb_free(payload_b64url);
1196+
flb_free(payload_b64);
1197+
flb_free(decoded_payload);
1198+
return -1;
1199+
}
1200+
1201+
// Extract numeric value
1202+
char *exp_str = decoded_payload + tokens[i].start;
1203+
int exp_len = tokens[i].end - tokens[i].start;
1204+
char exp_buf[32];
1205+
1206+
if (exp_len >= sizeof(exp_buf)) {
1207+
exp_len = sizeof(exp_buf) - 1;
1208+
}
1209+
1210+
strncpy(exp_buf, exp_str, exp_len);
1211+
exp_buf[exp_len] = '\0';
1212+
1213+
exp_value = (time_t) atoll(exp_buf);
1214+
break;
1215+
}
1216+
}
1217+
1218+
if (exp_value == 0) {
1219+
flb_free(tokens);
1220+
flb_free(payload_b64url);
1221+
flb_free(payload_b64);
1222+
flb_free(decoded_payload);
1223+
return -1;
11521224
}
11531225

11541226
ctx->security_token.expires_at = exp_value;
11551227

1156-
cJSON_Delete(json);
1228+
flb_free(tokens);
11571229
flb_free(payload_b64url);
11581230
flb_free(payload_b64);
11591231
flb_free(decoded_payload);

0 commit comments

Comments
 (0)