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_1 "\" target=\"_blank\">"
#define ALn_URL_ANCHOR_2 "</a>"
#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,
"<form method=\"post\" action=\"%s/%s\" id=\"%s\">"
"%s" // Parameters
"<input type=\"hidden\" name=\"usr\" value=\"",
Cfg_URL_SWAD_CGI,
Lan_STR_LANG_ID[Gbl.Prefs.Language],
Gbl.Usrs.Me.Logged ? Gbl.Form.UniqueId :
Gbl.Form.Id,
ParamsStr) < 0)
Err_NotEnoughMemoryExit ();
(*Link)->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,
"\">"
"<a href=\"\""
" onclick=\"document.getElementById('%s').submit();return false;\">",
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,
"<form method=\"post\" action=\"%s/%s\" id=\"%s\">"
"%s" // Parameters
"<input type=\"hidden\" name=\"usr\" value=\"",
Cfg_URL_SWAD_CGI,
Lan_STR_LANG_ID[Gbl.Prefs.Language],
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 *****/
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);
/***** Store second part of anchor *****/
if (asprintf (&(*Link)->NickAnchor[1].Str,
"\">"
"<a href=\"\""
" onclick=\"document.getElementById('%s').submit();return false;\">",
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,
"</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 *****/
(*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);
}
}

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.
*/
#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)

View File

@ -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);

View File

@ -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 ();

View File

@ -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 ();
}