88#define RC_CONVERSION_FILL (obj , obj_type , src_type ) memset((uint8_t*)obj + sizeof(src_type), 0, sizeof(obj_type) - sizeof(src_type))
99
1010/* https://media.retroachievements.org/Badge/123456_lock.png is 58 with null terminator */
11- #define RC_CLIENT_IMAGE_URL_BUFFER_SIZE 128
11+ #define RC_CLIENT_IMAGE_URL_BUFFER_SIZE 64
12+ /* https://media.retroachievements.org/UserPic/TwentyCharUserNameXX.png is 69 with null terminator */
13+ #define RC_CLIENT_USER_IMAGE_URL_BUFFER_SIZE 80
1214
1315typedef struct rc_client_external_conversions_t {
1416 rc_client_user_t user ;
1517 rc_client_game_t game ;
1618 rc_client_subset_t subsets [4 ];
1719 rc_client_achievement_t achievements [16 ];
18- char user_avatar_url [RC_CLIENT_IMAGE_URL_BUFFER_SIZE ];
20+ char user_avatar_url [RC_CLIENT_USER_IMAGE_URL_BUFFER_SIZE ];
1921 char game_badge_url [RC_CLIENT_IMAGE_URL_BUFFER_SIZE ];
2022 char subset_badge_url [4 ][RC_CLIENT_IMAGE_URL_BUFFER_SIZE ];
2123 char achievement_badge_url [16 ][RC_CLIENT_IMAGE_URL_BUFFER_SIZE ];
@@ -24,7 +26,7 @@ typedef struct rc_client_external_conversions_t {
2426 uint32_t next_achievement_index ;
2527} rc_client_external_conversions_t ;
2628
27- static const char * rc_client_external_build_avatar_url (char buffer [], uint32_t image_type , const char * image_name )
29+ static const char * rc_client_external_build_avatar_url (char buffer [], size_t buffer_size , uint32_t image_type , const char * image_name )
2830{
2931 rc_api_fetch_image_request_t image_request ;
3032 rc_api_request_t request ;
@@ -38,7 +40,7 @@ static const char* rc_client_external_build_avatar_url(char buffer[], uint32_t i
3840 if (result != RC_OK )
3941 return NULL ;
4042
41- strcpy_s (buffer , RC_CLIENT_IMAGE_URL_BUFFER_SIZE , request .url );
43+ snprintf (buffer , buffer_size , "%s" , request .url );
4244 return buffer ;
4345}
4446
@@ -69,7 +71,9 @@ const rc_client_user_t* rc_client_external_convert_v1_user(const rc_client_t* cl
6971 RC_CONVERSION_FILL (converted , rc_client_user_t , v1_rc_client_user_t );
7072
7173 converted -> avatar_url = rc_client_external_build_avatar_url (
72- client -> state .external_client_conversions -> user_avatar_url , RC_IMAGE_TYPE_USER , v1_user -> username );
74+ client -> state .external_client_conversions -> user_avatar_url ,
75+ sizeof (client -> state .external_client_conversions -> user_avatar_url ),
76+ RC_IMAGE_TYPE_USER , v1_user -> username );
7377
7478 return converted ;
7579}
@@ -88,7 +92,9 @@ const rc_client_game_t* rc_client_external_convert_v1_game(const rc_client_t* cl
8892 RC_CONVERSION_FILL (converted , rc_client_game_t , v1_rc_client_game_t );
8993
9094 converted -> badge_url = rc_client_external_build_avatar_url (
91- client -> state .external_client_conversions -> game_badge_url , RC_IMAGE_TYPE_GAME , v1_game -> badge_name );
95+ client -> state .external_client_conversions -> game_badge_url ,
96+ sizeof (client -> state .external_client_conversions -> game_badge_url ),
97+ RC_IMAGE_TYPE_GAME , v1_game -> badge_name );
9298
9399 return converted ;
94100}
@@ -123,7 +129,9 @@ const rc_client_subset_t* rc_client_external_convert_v1_subset(const rc_client_t
123129 memcpy (converted , v1_subset , sizeof (v1_rc_client_subset_t ));
124130 RC_CONVERSION_FILL (converted , rc_client_subset_t , v1_rc_client_subset_t );
125131
126- converted -> badge_url = rc_client_external_build_avatar_url (badge_url , RC_IMAGE_TYPE_GAME , v1_subset -> badge_name );
132+ converted -> badge_url = rc_client_external_build_avatar_url (badge_url ,
133+ sizeof (client -> state .external_client_conversions -> subset_badge_url [0 ]),
134+ RC_IMAGE_TYPE_GAME , v1_subset -> badge_name );
127135
128136 return converted ;
129137}
@@ -161,8 +169,12 @@ const rc_client_achievement_t* rc_client_external_convert_v1_achievement(const r
161169 memcpy (converted , v1_achievement , sizeof (v1_rc_client_achievement_t ));
162170 RC_CONVERSION_FILL (converted , rc_client_achievement_t , v1_rc_client_achievement_t );
163171
164- converted -> badge_url = rc_client_external_build_avatar_url (badge_url , RC_IMAGE_TYPE_ACHIEVEMENT , v1_achievement -> badge_name );
165- converted -> badge_locked_url = rc_client_external_build_avatar_url (badge_locked_url , RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED , v1_achievement -> badge_name );
172+ converted -> badge_url = rc_client_external_build_avatar_url (badge_url ,
173+ sizeof (client -> state .external_client_conversions -> achievement_badge_url [0 ]),
174+ RC_IMAGE_TYPE_ACHIEVEMENT , v1_achievement -> badge_name );
175+ converted -> badge_locked_url = rc_client_external_build_avatar_url (badge_locked_url ,
176+ sizeof (client -> state .external_client_conversions -> achievement_badge_locked_url [0 ]),
177+ RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED , v1_achievement -> badge_name );
166178
167179 return converted ;
168180}
@@ -246,9 +258,13 @@ rc_client_achievement_list_t* rc_client_external_convert_v1_achievement_list(con
246258 * achievement = & new_list -> achievements [num_achievements ++ ];
247259 memcpy (* achievement , * src_achievement , sizeof (* * src_achievement ));
248260
249- (* achievement )-> badge_url = rc_client_external_build_avatar_url (badge_url , RC_IMAGE_TYPE_ACHIEVEMENT , (* achievement )-> badge_name );
261+ (* achievement )-> badge_url = rc_client_external_build_avatar_url (badge_url ,
262+ sizeof (client -> state .external_client_conversions -> achievement_badge_url [0 ]),
263+ RC_IMAGE_TYPE_ACHIEVEMENT , (* achievement )-> badge_name );
250264 badge_url += RC_CLIENT_IMAGE_URL_BUFFER_SIZE ;
251- (* achievement )-> badge_locked_url = rc_client_external_build_avatar_url (badge_url , RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED , (* achievement )-> badge_name );
265+ (* achievement )-> badge_locked_url = rc_client_external_build_avatar_url (badge_url ,
266+ sizeof (client -> state .external_client_conversions -> achievement_badge_locked_url [0 ]),
267+ RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED , (* achievement )-> badge_name );
252268 badge_url += RC_CLIENT_IMAGE_URL_BUFFER_SIZE ;
253269 }
254270 }
0 commit comments