diff --git a/swad_autolink.c b/swad_autolink.c index 70f0b732..a3cc40a8 100644 --- a/swad_autolink.c +++ b/swad_autolink.c @@ -103,9 +103,11 @@ static void ALn_CopySubstring (const struct ALn_Substring *PtrSrc,char **PtrDst) #define ALn_URL_ANCHOR_0 "" #define ALn_URL_ANCHOR_2 "" + #define ALn_URL_ANCHOR_0_LENGTH (sizeof (ALn_URL_ANCHOR_0) - 1) #define ALn_URL_ANCHOR_1_LENGTH (sizeof (ALn_URL_ANCHOR_1) - 1) #define ALn_URL_ANCHOR_2_LENGTH (sizeof (ALn_URL_ANCHOR_2) - 1) + #define ALn_URL_ANCHOR_TOTAL_LENGTH (ALn_URL_ANCHOR_0_LENGTH + ALn_URL_ANCHOR_1_LENGTH + ALn_URL_ANCHOR_2_LENGTH) static const struct ALn_Substring URLAnchor[3] = @@ -202,11 +204,12 @@ void ALn_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre /* Check if the next char is the start of a nickname */ if ((Link->Type = ALn_CheckNickname (&PtrSrc,PrevCh, &Link,&LastLink)) == ALn_LINK_UNKNOWN) - { /* The next char is not the start of a URL or a nickname */ - PrevCh = *PtrSrc; - PtrSrc++; - } + if (*PtrSrc) // If not end reached + { + PrevCh = *PtrSrc; + PtrSrc++; + } /**********************************************************************/ /***** If there are one or more links (URLs or nicknames) in text *****/ @@ -216,7 +219,8 @@ void ALn_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre /***** Insert links from end to start of text, only if there is enough space available in text *****/ TxtLength = strlen (Txt); - if (TxtLength + LastLink->LengthAddedUpToHere <= MaxLength) + if (TxtLength + LastLink->LengthAddedUpToHere <= MaxLength) + { for (Link = LastLink; Link; Link = Link->Prev) @@ -241,9 +245,10 @@ void ALn_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre /***** Step 1: Move forward the text after the link (URL or nickname) (it's mandatory to do the copy in reverse order to avoid overwriting source) *****/ + PtrSrc = (Link == LastLink) ? Txt + TxtLength : - Link->Next->URLorNick.Str - 1, - PtrDst = PtrSrc + Link->LengthAddedUpToHere , + Link->Next->URLorNick.Str - 1; + PtrDst = PtrSrc + Link->LengthAddedUpToHere; Length = PtrSrc - (Link->URLorNick.Str + Link->URLorNick.Len - 1); for (i = 0; i < Length; @@ -258,28 +263,28 @@ void ALn_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre switch (Link->Type) { case ALn_LINK_URL: - if (Link->URLorNick.Len <= MaxCharsURLOnScreen) - ALn_CopySubstring (&Link->URLorNick,&PtrDst); - else - { - /* Limit the length of URL */ - if ((Limited.Str = malloc (Link->URLorNick.Len + 1)) == NULL) - Err_NotEnoughMemoryExit (); - strncpy (Limited.Str,Link->URLorNick.Str,Link->URLorNick.Len); - Limited.Str[Link->URLorNick.Len] = '\0'; - Limited.Len = Str_LimitLengthHTMLStr (Limited.Str,MaxCharsURLOnScreen); - ALn_CopySubstring (&Limited,&PtrDst); - free (Limited.Str); - } - break; + if (Link->URLorNick.Len <= MaxCharsURLOnScreen) + ALn_CopySubstring (&Link->URLorNick,&PtrDst); + else + { + /* Limit the length of URL */ + if ((Limited.Str = malloc (Link->URLorNick.Len + 1)) == NULL) + Err_NotEnoughMemoryExit (); + strncpy (Limited.Str,Link->URLorNick.Str,Link->URLorNick.Len); + Limited.Str[Link->URLorNick.Len] = '\0'; + Limited.Len = Str_LimitLengthHTMLStr (Limited.Str,MaxCharsURLOnScreen); + ALn_CopySubstring (&Limited,&PtrDst); + free (Limited.Str); + } + break; case ALn_LINK_NICK: ALn_CopySubstring (&Link->URLorNick,&PtrDst); - break; + break; default: - break; + break; } - /***** Step 4: Copy the second part of the anchor *****/ + /***** Step 4: Copy the second part of the anchor *****/ ALn_CopySubstring (Anchor[1],&PtrDst); /***** Step 5: Copy the link into the anchor @@ -290,6 +295,7 @@ void ALn_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre /***** Step 6: Copy the first part of the anchor *****/ ALn_CopySubstring (Anchor[0],&PtrDst); } + } } /***********************************/ @@ -512,88 +518,90 @@ static ALn_LinkType_t ALn_CheckNickname (char **PtrSrc,char PrevCh, if (NickSeemsValid) { - /***** Get user's code using nickname *****/ + /***** Create data for a user *****/ Usr_UsrDataConstructor (&UsrDat); - strncpy (NickWithoutArr,(*Link)->URLorNick.Str + 1,Length); - NickWithoutArr[Length] = '\0'; - if ((UsrDat.UsrCod = Nck_DB_GetUsrCodFromNickname (NickWithoutArr)) > 0) - { - Type = ALn_LINK_NICK; - Usr_GetUsrDataFromUsrCod (&UsrDat, - Usr_DONT_GET_PREFS, - Usr_DONT_GET_ROLE_IN_CURRENT_CRS); - } - if (Type == ALn_LINK_NICK) - { - /***** Reset anchors (checked on freeing) *****/ - (*Link)->NickAnchor[0].Str = - (*Link)->NickAnchor[1].Str = - (*Link)->NickAnchor[2].Str = NULL; + /***** Get user's code using nickname *****/ + strncpy (NickWithoutArr,(*Link)->URLorNick.Str + 1,Length); + NickWithoutArr[Length] = '\0'; + if ((UsrDat.UsrCod = Nck_DB_GetUsrCodFromNickname (NickWithoutArr)) > 0) + { + Type = ALn_LINK_NICK; + Usr_GetUsrDataFromUsrCod (&UsrDat, + Usr_DONT_GET_PREFS, + Usr_DONT_GET_ROLE_IN_CURRENT_CRS); + } - /***** Create id for this form *****/ - Gbl.Form.Num++; - if (Gbl.Usrs.Me.Logged) - snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId), - "form_%s_%d",Gbl.UniqueNameEncrypted,Gbl.Form.Num); - else - snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id), - "form_%d",Gbl.Form.Num); + if (Type == ALn_LINK_NICK) + { + /***** Reset anchors (checked on freeing) *****/ + (*Link)->NickAnchor[0].Str = + (*Link)->NickAnchor[1].Str = + (*Link)->NickAnchor[2].Str = NULL; - /***** Store first part of anchor *****/ - Frm_SetParamsForm (ParamsStr,ActSeeOthPubPrf,true); - if (asprintf (&(*Link)->NickAnchor[0].Str, - "
" - "%s" // Parameters - "NickAnchor[0].Len = strlen ((*Link)->NickAnchor[0].Str); + /***** Create id for this form *****/ + Gbl.Form.Num++; + if (Gbl.Usrs.Me.Logged) + snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId), + "form_%s_%d",Gbl.UniqueNameEncrypted,Gbl.Form.Num); + else + snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id), + "form_%d",Gbl.Form.Num); - /***** Store second part of anchor *****/ - if (asprintf (&(*Link)->NickAnchor[1].Str, - "\">" - "", - Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId : - Gbl.Form.Id) < 0) - Err_NotEnoughMemoryExit (); - (*Link)->NickAnchor[1].Len = strlen ((*Link)->NickAnchor[1].Str); + /***** Store first part of anchor *****/ + Frm_SetParamsForm (ParamsStr,ActSeeOthPubPrf,true); + if (asprintf (&(*Link)->NickAnchor[0].Str, + "" + "%s" // Parameters + "NickAnchor[0].Len = strlen ((*Link)->NickAnchor[0].Str); - /***** Store third part of anchor *****/ - ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL); - Pho_BuildHTMLUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL : - NULL, - ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM, - &CaptionStr, - &ImgStr); - if (asprintf (&(*Link)->NickAnchor[2].Str, - "
%s%s", - CaptionStr, - ImgStr) < 0) - Err_NotEnoughMemoryExit (); - free (ImgStr); - free (CaptionStr); - (*Link)->NickAnchor[2].Len = strlen ((*Link)->NickAnchor[2].Str); + /***** Store second part of anchor *****/ + if (asprintf (&(*Link)->NickAnchor[1].Str, + "\">" + "", + Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId : + Gbl.Form.Id) < 0) + Err_NotEnoughMemoryExit (); + (*Link)->NickAnchor[1].Len = strlen ((*Link)->NickAnchor[1].Str); - /***** Free memory used for user's data *****/ - Usr_UsrDataDestructor (&UsrDat); + /***** Store third part of anchor *****/ + ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL); + Pho_BuildHTMLUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL : + NULL, + ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM, + &CaptionStr, + &ImgStr); + if (asprintf (&(*Link)->NickAnchor[2].Str, + "%s%s", + CaptionStr, + ImgStr) < 0) + Err_NotEnoughMemoryExit (); + free (ImgStr); + free (CaptionStr); + (*Link)->NickAnchor[2].Len = strlen ((*Link)->NickAnchor[2].Str); - /***** Compute number of bytes added until here *****/ - (*Link)->LengthAddedUpToHere = (*Link)->Prev ? (*Link)->Prev->LengthAddedUpToHere : - 0; - (*Link)->LengthAddedUpToHere += (*Link)->NickAnchor[0].Len + - (*Link)->URLorNick.Len + - (*Link)->NickAnchor[1].Len + - (*Link)->NickAnchor[2].Len; + /***** Compute number of bytes added until here *****/ + (*Link)->LengthAddedUpToHere = (*Link)->Prev ? (*Link)->Prev->LengthAddedUpToHere : + 0; + (*Link)->LengthAddedUpToHere += (*Link)->NickAnchor[0].Len + + (*Link)->URLorNick.Len + + (*Link)->NickAnchor[1].Len + + (*Link)->NickAnchor[2].Len; - /***** Create next link *****/ - ALn_CreateNextLink (Link,LastLink); - } + /***** Create next link *****/ + ALn_CreateNextLink (Link,LastLink); + } + + /***** Free memory used for user's data *****/ + Usr_UsrDataDestructor (&UsrDat); } } diff --git a/swad_changelog.h b/swad_changelog.h index d8c8e978..f16d87d9 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -606,10 +606,11 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate TODO: Attach pdf files in multimedia. */ -#define Log_PLATFORM_VERSION "SWAD 21.95.2 (2022-04-30)" +#define Log_PLATFORM_VERSION "SWAD 21.95.2 (2022-05-09)" #define CSS_FILE "swad21.95.css" #define JS_FILE "swad21.92.js" /* + Version 21.95.3: May 09, 2022 Fixed bug inserting automatic links. Reported by Javier Fernández Baldomero and others. (323439 lines) Version 21.95.2: Apr 30, 2022 Fixed issue in most frequent actions. Reported by Pablo Millán Cubero. (323423 lines) Version 21.95.1: Apr 27, 2022 Fixing design of dark theme. (323406 lines) Version 21.95: Apr 27, 2022 Fixing design of dark theme. (323404 lines) diff --git a/swad_media.c b/swad_media.c index 91f5de6e..3d62f41a 100644 --- a/swad_media.c +++ b/swad_media.c @@ -249,6 +249,13 @@ void Med_GetMediaDataByCod (struct Med_Media *Media) unsigned NumRows; size_t Length; + /***** Trivial check: media code should be > 0 *****/ + if (Media->MedCod <= 0) + { + Med_ResetMedia (Media); + return; + } + /***** Get data of a media from database *****/ NumRows = Med_DB_GetMediaDataByCod (&mysql_res,Media->MedCod); diff --git a/swad_timeline_note.c b/swad_timeline_note.c index 8733db8b..0e17d31b 100644 --- a/swad_timeline_note.c +++ b/swad_timeline_note.c @@ -158,8 +158,8 @@ void TmlNot_ShowHighlightedNote (struct Tml_Timeline *Timeline, /* Check and write note with top message */ TmlNot_CheckAndWriteNoteWithTopMsg (Timeline,Not, - TopMessages[NotifyEvent], - PublisherDat.UsrCod); + TopMessages[NotifyEvent], + PublisherDat.UsrCod); /* End container */ HTM_DIV_End (); diff --git a/swad_timeline_post.c b/swad_timeline_post.c index 76e77a96..9990a4f5 100644 --- a/swad_timeline_post.c +++ b/swad_timeline_post.c @@ -77,11 +77,11 @@ void TmlPst_GetAndWritePost (long PstCod) /***** Initialize media *****/ Med_MediaConstructor (&Content.Media); - /***** Get post content from database *****/ - TmlPst_GetPostContent (PstCod,&Content); + /***** Get post content from database *****/ + TmlPst_GetPostContent (PstCod,&Content); - /***** Show post content *****/ - TmlPst_ShowPostContent (&Content); + /***** Show post content *****/ + TmlPst_ShowPostContent (&Content); /***** Free media *****/ Med_MediaDestructor (&Content.Media); @@ -114,7 +114,10 @@ static void TmlPst_GetPostContent (long PstCod,struct TmlPst_Content *Content) Med_GetMediaDataByCod (&Content->Media); } else + { Content->Txt[0] = '\0'; + Med_ResetMedia (&Content->Media); + } /***** Free structure that stores the query result *****/ DB_FreeMySQLResult (&mysql_res); @@ -126,11 +129,14 @@ static void TmlPst_GetPostContent (long PstCod,struct TmlPst_Content *Content) static void TmlPst_ShowPostContent (struct TmlPst_Content *Content) { + /***** Trivial check *****/ + if (Content == NULL) + Err_ShowErrorAndExit ("Wrong content."); + /***** Write content text *****/ if (Content->Txt[0]) { - HTM_DIV_Begin ("class=\"Tml_TXT Tml_TXT_%s\"", - The_GetSuffix ()); + HTM_DIV_Begin ("class=\"Tml_TXT Tml_TXT_%s\"",The_GetSuffix ()); Msg_WriteMsgContent (Content->Txt,true,false); HTM_DIV_End (); }