From b60cac53e5d96e3f9276c8d2263bd6c5f25557fd Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Fri, 24 Feb 2023 00:17:56 +0000 Subject: [PATCH] Make JsonValueString() call StrDuplicate(); refactor code to behave properly. --- TODO.txt | 5 ++--- contrib/development.conf | 2 +- src/Json.c | 9 ++++++++- src/Matrix.c | 8 ++++---- src/Routes/RouteLogin.c | 21 ++++++++------------- src/Routes/RouteMatrix.c | 2 +- src/Routes/RouteRefresh.c | 6 +++--- src/Routes/RouteRegister.c | 23 ++++++++--------------- src/Uia.c | 9 ++++++--- src/User.c | 31 ++++++++++++++++++++++++------- src/include/User.h | 3 +++ 11 files changed, 68 insertions(+), 51 deletions(-) diff --git a/TODO.txt b/TODO.txt index f55b3b0..8540f4a 100644 --- a/TODO.txt +++ b/TODO.txt @@ -28,8 +28,6 @@ Milestone: v0.2.0 [x] Non-JSON endpoints [x] Home page (like Synapse's "it works!") -[!] Document HashMapGetKey() - - See Refactor below [ ] Document new User functions [ ] Document new JSON functions @@ -39,7 +37,8 @@ Milestone: v0.2.0 done with them. [x] Remove HashMapGetKey() function [x] HashMap - [ ] JsonValueString() + [x] JsonValueString() + [ ] Db Milestone: v0.3.0 ----------------- diff --git a/contrib/development.conf b/contrib/development.conf index da6aa0b..d293cd4 100644 --- a/contrib/development.conf +++ b/contrib/development.conf @@ -7,7 +7,7 @@ "threads": 2, "log": { "output": "stdout", - "level": "debug", + "//level": "debug", "timestampFormat": "none", "color": true } diff --git a/src/Json.c b/src/Json.c index 1ffe5fc..be4d783 100644 --- a/src/Json.c +++ b/src/Json.c @@ -174,7 +174,13 @@ JsonValueString(char *string) } value->type = JSON_STRING; - value->as.string = string; + + value->as.string = StrDuplicate(string); + if (!value->as.string) + { + Free(value); + return NULL; + } return value; } @@ -913,6 +919,7 @@ JsonDecodeValue(JsonParserState * state) } strcpy(strValue, state->token); value = JsonValueString(strValue); + Free(strValue); break; case TOKEN_INTEGER: value = JsonValueInteger(atol(state->token)); diff --git a/src/Matrix.c b/src/Matrix.c index 018fc10..d4378ff 100644 --- a/src/Matrix.c +++ b/src/Matrix.c @@ -304,8 +304,8 @@ MatrixErrorCreate(MatrixError errorArg) return NULL; } - HashMapSet(errorObj, "errcode", JsonValueString(StrDuplicate(errcode))); - HashMapSet(errorObj, "error", JsonValueString(StrDuplicate(error))); + HashMapSet(errorObj, "errcode", JsonValueString(errcode)); + HashMapSet(errorObj, "error", JsonValueString(error)); return errorObj; } @@ -378,14 +378,14 @@ MatrixClientWellKnown(char *base, char *identity) response = HashMapCreate(); homeserver = HashMapCreate(); - HashMapSet(homeserver, "base_url", JsonValueString(StrDuplicate(base))); + HashMapSet(homeserver, "base_url", JsonValueString(base)); HashMapSet(response, "m.homeserver", JsonValueObject(homeserver)); if (identity) { HashMap *identityServer = HashMapCreate(); - HashMapSet(identityServer, "base_url", JsonValueString(StrDuplicate(identity))); + HashMapSet(identityServer, "base_url", JsonValueString(identity)); HashMapSet(response, "m.identity_server", identityServer); } diff --git a/src/Routes/RouteLogin.c b/src/Routes/RouteLogin.c index 996a390..332d217 100644 --- a/src/Routes/RouteLogin.c +++ b/src/Routes/RouteLogin.c @@ -54,6 +54,7 @@ ROUTE_IMPL(RouteLogin, args) User *user; UserLoginInfo *loginInfo; + char *fullUsername; if (MATRIX_PATH_PARTS(args->path) > 0) { @@ -68,8 +69,7 @@ ROUTE_IMPL(RouteLogin, args) enabledFlows = ArrayCreate(); pwdFlow = HashMapCreate(); - HashMapSet(pwdFlow, "type", - JsonValueString(StrDuplicate("m.login.password"))); + HashMapSet(pwdFlow, "type", JsonValueString("m.login.password")); ArrayAdd(enabledFlows, JsonValueObject(pwdFlow)); HashMapSet(response, "flows", JsonValueArray(enabledFlows)); break; @@ -261,23 +261,18 @@ ROUTE_IMPL(RouteLogin, args) JsonValueString(loginInfo->refreshToken)); } - HashMapSet(response, "user_id", - JsonValueString( - StrConcat(4, "@", UserGetName(user), ":", - args->matrixArgs->config->serverName))); + fullUsername = StrConcat(4, "@", UserGetName(user), ":", + args->matrixArgs->config->serverName); + HashMapSet(response, "user_id", JsonValueString(fullUsername)); + Free(fullUsername); HashMapSet(response, "well_known", JsonValueObject( MatrixClientWellKnown(args->matrixArgs->config->baseUrl, args->matrixArgs->config->identityServer))); - Free(loginInfo->accessToken->user); - - /* - * Don't need to free other members; they're attached to the JSON - * response, they will be freed after the response is sent. - */ - Free(loginInfo->accessToken); + UserAccessTokenFree(loginInfo->accessToken); + Free(loginInfo->refreshToken); Free(loginInfo); UserUnlock(user); diff --git a/src/Routes/RouteMatrix.c b/src/Routes/RouteMatrix.c index 8872981..1d30c42 100644 --- a/src/Routes/RouteMatrix.c +++ b/src/Routes/RouteMatrix.c @@ -51,7 +51,7 @@ ROUTE_IMPL(RouteMatrix, args) Free(pathPart); - ArrayAdd(versions, JsonValueString(StrDuplicate("v1.6"))); + ArrayAdd(versions, JsonValueString("v1.6")); response = HashMapCreate(); HashMapSet(response, "versions", JsonValueArray(versions)); diff --git a/src/Routes/RouteRefresh.c b/src/Routes/RouteRefresh.c index 959483e..84fc727 100644 --- a/src/Routes/RouteRefresh.c +++ b/src/Routes/RouteRefresh.c @@ -145,15 +145,15 @@ ROUTE_IMPL(RouteRefresh, args) DbDelete(db, 3, "tokens", "access", oldAccessToken); /* Update the refresh token to point to the new access token */ - JsonValueFree(HashMapSet(DbJson(rtRef), "refreshes", JsonValueString(StrDuplicate(newAccessToken->string)))); + JsonValueFree(HashMapSet(DbJson(rtRef), "refreshes", JsonValueString(newAccessToken->string))); /* Return the new access token and expiration timestamp to the * client */ response = HashMapCreate(); - HashMapSet(response, "access_token", JsonValueString(StrDuplicate(newAccessToken->string))); + HashMapSet(response, "access_token", JsonValueString(newAccessToken->string)); HashMapSet(response, "expires_in_ms", JsonValueInteger(newAccessToken->lifetime)); - Free(newAccessToken); + UserAccessTokenFree(newAccessToken); finish: JsonFree(request); diff --git a/src/Routes/RouteRegister.c b/src/Routes/RouteRegister.c index faf95bf..6425fce 100644 --- a/src/Routes/RouteRegister.c +++ b/src/Routes/RouteRegister.c @@ -48,6 +48,7 @@ ROUTE_IMPL(RouteRegister, args) int refreshToken = 0; int inhibitLogin = 0; char *deviceId = NULL; + char *fullUsername; Db *db = args->matrixArgs->db; LogConfig *lc = args->matrixArgs->lc; @@ -205,18 +206,13 @@ ROUTE_IMPL(RouteRegister, args) refreshToken = JsonValueAsBoolean(val); } - /* These values are already set */ - (void) refreshToken; - (void) inhibitLogin; - - /* These may be NULL */ - (void) initialDeviceDisplayName; - (void) deviceId; - user = UserCreate(db, username, password); response = HashMapCreate(); - HashMapSet(response, "user_id", JsonValueString(StrConcat(4, "@", - UserGetName(user), ":", args->matrixArgs->config->serverName))); + + fullUsername = StrConcat(4, "@", UserGetName(user), ":", args->matrixArgs->config->serverName); + HashMapSet(response, "user_id", JsonValueString(fullUsername)); + Free(fullUsername); + HttpResponseStatus(args->context, HTTP_OK); if (!inhibitLogin) { @@ -236,11 +232,8 @@ ROUTE_IMPL(RouteRegister, args) JsonValueString(loginInfo->refreshToken)); } - /* - * Don't need to free members; they're attached to the JSON response, - * they will be freed after the response is sent. - */ - Free(loginInfo->accessToken); + UserAccessTokenFree(loginInfo->accessToken); + Free(loginInfo->refreshToken); Free(loginInfo); } diff --git a/src/Uia.c b/src/Uia.c index eeadc6b..e63d886 100644 --- a/src/Uia.c +++ b/src/Uia.c @@ -89,7 +89,7 @@ BuildFlows(Array * flows) { UiaStage *stage = ArrayGet(stages, i); - ArrayAdd(responseStages, JsonValueString(StrDuplicate(stage->type))); + ArrayAdd(responseStages, JsonValueString(stage->type)); if (stage->params) { JsonValueFree(HashMapSet(responseParams, stage->type, JsonValueObject(stage->params))); @@ -163,7 +163,7 @@ BuildResponse(Array * flows, char *session, Db * db, HashMap ** response) { char *stage = JsonValueAsString(ArrayGet(dbCompleted, i)); - ArrayAdd(completed, JsonValueString(StrDuplicate(stage))); + ArrayAdd(completed, JsonValueString(stage)); } HashMapSet(*response, "completed", JsonValueArray(completed)); @@ -296,7 +296,10 @@ finish: { UiaStage *stage = ArrayGet(stages, j); - Free(stage); /* Members are referenced elsewhere */ + Free(stage->type); + /* stage->params, if not null, is referenced in the + * response body. */ + Free(stage); } ArrayFree(stages); } diff --git a/src/User.c b/src/User.c index 85e585d..b86d837 100644 --- a/src/User.c +++ b/src/User.c @@ -278,7 +278,7 @@ UserLogin(User * user, char *password, char *deviceId, char *deviceDisplayName, rtRef = DbCreate(user->db, 3, "tokens", "refresh", result->refreshToken); HashMapSet(DbJson(rtRef), "refreshes", - JsonValueString(StrDuplicate(result->accessToken->string))); + JsonValueString(result->accessToken->string)); DbUnlock(user->db, rtRef); } @@ -317,7 +317,7 @@ UserLogin(User * user, char *password, char *deviceId, char *deviceDisplayName, if (deviceDisplayName) { HashMapSet(device, "displayName", - JsonValueString(StrDuplicate(deviceDisplayName))); + JsonValueString(deviceDisplayName)); } } @@ -327,11 +327,11 @@ UserLogin(User * user, char *password, char *deviceId, char *deviceDisplayName, if (result->refreshToken) { HashMapSet(device, "refreshToken", - JsonValueString(StrDuplicate(result->refreshToken))); + JsonValueString(result->refreshToken)); } HashMapSet(device, "accessToken", - JsonValueString(StrDuplicate(result->accessToken->string))); + JsonValueString(result->accessToken->string)); return result; } @@ -400,11 +400,14 @@ UserSetPassword(User * user, char *password) salt = StrRandom(16); tmpstr = StrConcat(2, password, salt); hash = Sha256(tmpstr); - Free(tmpstr); JsonValueFree(HashMapSet(json, "salt", JsonValueString(salt))); JsonValueFree(HashMapSet(json, "password", JsonValueString(hash))); + Free(salt); + Free(hash); + Free(tmpstr); + return 1; } @@ -493,8 +496,8 @@ UserAccessTokenSave(Db * db, UserAccessToken * token) json = DbJson(ref); - HashMapSet(json, "user", JsonValueString(StrDuplicate(token->user))); - HashMapSet(json, "device", JsonValueString(StrDuplicate(token->deviceId))); + HashMapSet(json, "user", JsonValueString(token->user)); + HashMapSet(json, "device", JsonValueString(token->deviceId)); if (token->lifetime) { @@ -504,6 +507,20 @@ UserAccessTokenSave(Db * db, UserAccessToken * token) return DbUnlock(db, ref); } +void +UserAccessTokenFree(UserAccessToken * token) +{ + if (!token) + { + return; + } + + Free(token->user); + Free(token->string); + Free(token->deviceId); + Free(token); +} + int UserDeleteToken(User * user, char *token) { diff --git a/src/include/User.h b/src/include/User.h index b8bbf85..3b26af6 100644 --- a/src/include/User.h +++ b/src/include/User.h @@ -87,6 +87,9 @@ extern UserAccessToken * extern int UserAccessTokenSave(Db *, UserAccessToken *); +extern void + UserAccessTokenFree(UserAccessToken *); + extern int UserDeleteToken(User *, char *);