Version 21.95.3: May 09, 2022 Fixed bug inserting automatic links. Reported by Javier Fernández Baldomero and others.

This commit is contained in:
acanas 2022-05-09 21:39:00 +02:00
parent 0fa596df82
commit 670522e4d6
5 changed files with 128 additions and 106 deletions

View File

@ -103,9 +103,11 @@ static void ALn_CopySubstring (const struct ALn_Substring *PtrSrc,char **PtrDst)
#define ALn_URL_ANCHOR_0 "<a href=\"" #define ALn_URL_ANCHOR_0 "<a href=\""
#define ALn_URL_ANCHOR_1 "\" target=\"_blank\">" #define ALn_URL_ANCHOR_1 "\" target=\"_blank\">"
#define ALn_URL_ANCHOR_2 "</a>" #define ALn_URL_ANCHOR_2 "</a>"
#define ALn_URL_ANCHOR_0_LENGTH (sizeof (ALn_URL_ANCHOR_0) - 1) #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_1_LENGTH (sizeof (ALn_URL_ANCHOR_1) - 1)
#define ALn_URL_ANCHOR_2_LENGTH (sizeof (ALn_URL_ANCHOR_2) - 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) #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] = 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 */ /* Check if the next char is the start of a nickname */
if ((Link->Type = ALn_CheckNickname (&PtrSrc,PrevCh, if ((Link->Type = ALn_CheckNickname (&PtrSrc,PrevCh,
&Link,&LastLink)) == ALn_LINK_UNKNOWN) &Link,&LastLink)) == ALn_LINK_UNKNOWN)
{
/* The next char is not the start of a URL or a nickname */ /* The next char is not the start of a URL or a nickname */
PrevCh = *PtrSrc; if (*PtrSrc) // If not end reached
PtrSrc++; {
} PrevCh = *PtrSrc;
PtrSrc++;
}
/**********************************************************************/ /**********************************************************************/
/***** If there are one or more links (URLs or nicknames) in text *****/ /***** 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, /***** Insert links from end to start of text,
only if there is enough space available in text *****/ only if there is enough space available in text *****/
TxtLength = strlen (Txt); TxtLength = strlen (Txt);
if (TxtLength + LastLink->LengthAddedUpToHere <= MaxLength) if (TxtLength + LastLink->LengthAddedUpToHere <= MaxLength)
{
for (Link = LastLink; for (Link = LastLink;
Link; Link;
Link = Link->Prev) 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) /***** Step 1: Move forward the text after the link (URL or nickname)
(it's mandatory to do the copy in reverse order (it's mandatory to do the copy in reverse order
to avoid overwriting source) *****/ to avoid overwriting source) *****/
PtrSrc = (Link == LastLink) ? Txt + TxtLength : PtrSrc = (Link == LastLink) ? Txt + TxtLength :
Link->Next->URLorNick.Str - 1, Link->Next->URLorNick.Str - 1;
PtrDst = PtrSrc + Link->LengthAddedUpToHere , PtrDst = PtrSrc + Link->LengthAddedUpToHere;
Length = PtrSrc - (Link->URLorNick.Str + Link->URLorNick.Len - 1); Length = PtrSrc - (Link->URLorNick.Str + Link->URLorNick.Len - 1);
for (i = 0; for (i = 0;
i < Length; i < Length;
@ -258,28 +263,28 @@ void ALn_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre
switch (Link->Type) switch (Link->Type)
{ {
case ALn_LINK_URL: case ALn_LINK_URL:
if (Link->URLorNick.Len <= MaxCharsURLOnScreen) if (Link->URLorNick.Len <= MaxCharsURLOnScreen)
ALn_CopySubstring (&Link->URLorNick,&PtrDst); ALn_CopySubstring (&Link->URLorNick,&PtrDst);
else else
{ {
/* Limit the length of URL */ /* Limit the length of URL */
if ((Limited.Str = malloc (Link->URLorNick.Len + 1)) == NULL) if ((Limited.Str = malloc (Link->URLorNick.Len + 1)) == NULL)
Err_NotEnoughMemoryExit (); Err_NotEnoughMemoryExit ();
strncpy (Limited.Str,Link->URLorNick.Str,Link->URLorNick.Len); strncpy (Limited.Str,Link->URLorNick.Str,Link->URLorNick.Len);
Limited.Str[Link->URLorNick.Len] = '\0'; Limited.Str[Link->URLorNick.Len] = '\0';
Limited.Len = Str_LimitLengthHTMLStr (Limited.Str,MaxCharsURLOnScreen); Limited.Len = Str_LimitLengthHTMLStr (Limited.Str,MaxCharsURLOnScreen);
ALn_CopySubstring (&Limited,&PtrDst); ALn_CopySubstring (&Limited,&PtrDst);
free (Limited.Str); free (Limited.Str);
} }
break; break;
case ALn_LINK_NICK: case ALn_LINK_NICK:
ALn_CopySubstring (&Link->URLorNick,&PtrDst); ALn_CopySubstring (&Link->URLorNick,&PtrDst);
break; break;
default: 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); ALn_CopySubstring (Anchor[1],&PtrDst);
/***** Step 5: Copy the link into the anchor /***** 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 *****/ /***** Step 6: Copy the first part of the anchor *****/
ALn_CopySubstring (Anchor[0],&PtrDst); ALn_CopySubstring (Anchor[0],&PtrDst);
} }
}
} }
/***********************************/ /***********************************/
@ -512,88 +518,90 @@ static ALn_LinkType_t ALn_CheckNickname (char **PtrSrc,char PrevCh,
if (NickSeemsValid) if (NickSeemsValid)
{ {
/***** Get user's code using nickname *****/ /***** Create data for a user *****/
Usr_UsrDataConstructor (&UsrDat); 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) /***** Get user's code using nickname *****/
{ strncpy (NickWithoutArr,(*Link)->URLorNick.Str + 1,Length);
/***** Reset anchors (checked on freeing) *****/ NickWithoutArr[Length] = '\0';
(*Link)->NickAnchor[0].Str = if ((UsrDat.UsrCod = Nck_DB_GetUsrCodFromNickname (NickWithoutArr)) > 0)
(*Link)->NickAnchor[1].Str = {
(*Link)->NickAnchor[2].Str = NULL; Type = ALn_LINK_NICK;
Usr_GetUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
}
/***** Create id for this form *****/ if (Type == ALn_LINK_NICK)
Gbl.Form.Num++; {
if (Gbl.Usrs.Me.Logged) /***** Reset anchors (checked on freeing) *****/
snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId), (*Link)->NickAnchor[0].Str =
"form_%s_%d",Gbl.UniqueNameEncrypted,Gbl.Form.Num); (*Link)->NickAnchor[1].Str =
else (*Link)->NickAnchor[2].Str = NULL;
snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id),
"form_%d",Gbl.Form.Num);
/***** Store first part of anchor *****/ /***** Create id for this form *****/
Frm_SetParamsForm (ParamsStr,ActSeeOthPubPrf,true); Gbl.Form.Num++;
if (asprintf (&(*Link)->NickAnchor[0].Str, if (Gbl.Usrs.Me.Logged)
"<form method=\"post\" action=\"%s/%s\" id=\"%s\">" snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId),
"%s" // Parameters "form_%s_%d",Gbl.UniqueNameEncrypted,Gbl.Form.Num);
"<input type=\"hidden\" name=\"usr\" value=\"", else
Cfg_URL_SWAD_CGI, snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id),
Lan_STR_LANG_ID[Gbl.Prefs.Language], "form_%d",Gbl.Form.Num);
Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
Gbl.Form.Id,
ParamsStr) < 0)
Err_NotEnoughMemoryExit ();
(*Link)->NickAnchor[0].Len = strlen ((*Link)->NickAnchor[0].Str);
/***** Store second part of anchor *****/ /***** Store first part of anchor *****/
if (asprintf (&(*Link)->NickAnchor[1].Str, Frm_SetParamsForm (ParamsStr,ActSeeOthPubPrf,true);
"\">" if (asprintf (&(*Link)->NickAnchor[0].Str,
"<a href=\"\"" "<form method=\"post\" action=\"%s/%s\" id=\"%s\">"
" onclick=\"document.getElementById('%s').submit();return false;\">", "%s" // Parameters
Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId : "<input type=\"hidden\" name=\"usr\" value=\"",
Gbl.Form.Id) < 0) Cfg_URL_SWAD_CGI,
Err_NotEnoughMemoryExit (); Lan_STR_LANG_ID[Gbl.Prefs.Language],
(*Link)->NickAnchor[1].Len = strlen ((*Link)->NickAnchor[1].Str); Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
Gbl.Form.Id,
ParamsStr) < 0)
Err_NotEnoughMemoryExit ();
(*Link)->NickAnchor[0].Len = strlen ((*Link)->NickAnchor[0].Str);
/***** Store third part of anchor *****/ /***** Store second part of anchor *****/
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL); if (asprintf (&(*Link)->NickAnchor[1].Str,
Pho_BuildHTMLUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL : "\">"
NULL, "<a href=\"\""
ClassPhoto[Gbl.Prefs.PhotoShape],Pho_ZOOM, " onclick=\"document.getElementById('%s').submit();return false;\">",
&CaptionStr, Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
&ImgStr); Gbl.Form.Id) < 0)
if (asprintf (&(*Link)->NickAnchor[2].Str, Err_NotEnoughMemoryExit ();
"</a></form>%s%s", (*Link)->NickAnchor[1].Len = strlen ((*Link)->NickAnchor[1].Str);
CaptionStr,
ImgStr) < 0)
Err_NotEnoughMemoryExit ();
free (ImgStr);
free (CaptionStr);
(*Link)->NickAnchor[2].Len = strlen ((*Link)->NickAnchor[2].Str);
/***** Free memory used for user's data *****/ /***** Store third part of anchor *****/
Usr_UsrDataDestructor (&UsrDat); 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,
"</a></form>%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 *****/ /***** Compute number of bytes added until here *****/
(*Link)->LengthAddedUpToHere = (*Link)->Prev ? (*Link)->Prev->LengthAddedUpToHere : (*Link)->LengthAddedUpToHere = (*Link)->Prev ? (*Link)->Prev->LengthAddedUpToHere :
0; 0;
(*Link)->LengthAddedUpToHere += (*Link)->NickAnchor[0].Len + (*Link)->LengthAddedUpToHere += (*Link)->NickAnchor[0].Len +
(*Link)->URLorNick.Len + (*Link)->URLorNick.Len +
(*Link)->NickAnchor[1].Len + (*Link)->NickAnchor[1].Len +
(*Link)->NickAnchor[2].Len; (*Link)->NickAnchor[2].Len;
/***** Create next link *****/ /***** Create next link *****/
ALn_CreateNextLink (Link,LastLink); ALn_CreateNextLink (Link,LastLink);
} }
/***** Free memory used for user's data *****/
Usr_UsrDataDestructor (&UsrDat);
} }
} }

View File

@ -606,10 +606,11 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate
TODO: Attach pdf files in multimedia. 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 CSS_FILE "swad21.95.css"
#define JS_FILE "swad21.92.js" #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.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.1: Apr 27, 2022 Fixing design of dark theme. (323406 lines)
Version 21.95: Apr 27, 2022 Fixing design of dark theme. (323404 lines) Version 21.95: Apr 27, 2022 Fixing design of dark theme. (323404 lines)

View File

@ -249,6 +249,13 @@ void Med_GetMediaDataByCod (struct Med_Media *Media)
unsigned NumRows; unsigned NumRows;
size_t Length; 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 *****/ /***** Get data of a media from database *****/
NumRows = Med_DB_GetMediaDataByCod (&mysql_res,Media->MedCod); NumRows = Med_DB_GetMediaDataByCod (&mysql_res,Media->MedCod);

View File

@ -158,8 +158,8 @@ void TmlNot_ShowHighlightedNote (struct Tml_Timeline *Timeline,
/* Check and write note with top message */ /* Check and write note with top message */
TmlNot_CheckAndWriteNoteWithTopMsg (Timeline,Not, TmlNot_CheckAndWriteNoteWithTopMsg (Timeline,Not,
TopMessages[NotifyEvent], TopMessages[NotifyEvent],
PublisherDat.UsrCod); PublisherDat.UsrCod);
/* End container */ /* End container */
HTM_DIV_End (); HTM_DIV_End ();

View File

@ -77,11 +77,11 @@ void TmlPst_GetAndWritePost (long PstCod)
/***** Initialize media *****/ /***** Initialize media *****/
Med_MediaConstructor (&Content.Media); Med_MediaConstructor (&Content.Media);
/***** Get post content from database *****/ /***** Get post content from database *****/
TmlPst_GetPostContent (PstCod,&Content); TmlPst_GetPostContent (PstCod,&Content);
/***** Show post content *****/ /***** Show post content *****/
TmlPst_ShowPostContent (&Content); TmlPst_ShowPostContent (&Content);
/***** Free media *****/ /***** Free media *****/
Med_MediaDestructor (&Content.Media); Med_MediaDestructor (&Content.Media);
@ -114,7 +114,10 @@ static void TmlPst_GetPostContent (long PstCod,struct TmlPst_Content *Content)
Med_GetMediaDataByCod (&Content->Media); Med_GetMediaDataByCod (&Content->Media);
} }
else else
{
Content->Txt[0] = '\0'; Content->Txt[0] = '\0';
Med_ResetMedia (&Content->Media);
}
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); 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) static void TmlPst_ShowPostContent (struct TmlPst_Content *Content)
{ {
/***** Trivial check *****/
if (Content == NULL)
Err_ShowErrorAndExit ("Wrong content.");
/***** Write content text *****/ /***** Write content text *****/
if (Content->Txt[0]) if (Content->Txt[0])
{ {
HTM_DIV_Begin ("class=\"Tml_TXT Tml_TXT_%s\"", HTM_DIV_Begin ("class=\"Tml_TXT Tml_TXT_%s\"",The_GetSuffix ());
The_GetSuffix ());
Msg_WriteMsgContent (Content->Txt,true,false); Msg_WriteMsgContent (Content->Txt,true,false);
HTM_DIV_End (); HTM_DIV_End ();
} }