Skip to content
This repository was archived by the owner on Sep 8, 2021. It is now read-only.

Commit c1452b0

Browse files
committed
Merge branch 'bugfix-10983' into release-6.1.0
2 parents ff936b6 + 5065f95 commit c1452b0

File tree

4 files changed

+82
-39
lines changed

4 files changed

+82
-39
lines changed

docs/notes/bugfix-10983.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Images with filenames that look like URLs can cause slowdown.
2+
Previously, if an image was set with a filename that roughly looked like a URL, it would cause an attempt to load the URL repeatedly. This could cause slowdown or, in the worse case, an infinite recursive loop.
3+
Now, the engine checks filenames more closely to see if they really could be URLs before attempting a fetch, and if a fetch is attempted it will only occur once and not retried if it fails.
4+

engine/src/image_rep.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ class MCReferencedImageRep : public MCEncodedImageRep
180180
// hold data from remote image
181181
void *m_url_data;
182182
uindex_t m_url_data_size;
183+
184+
// MW-2013-09-25: [[ Bug 10983 ]] Indicates whether an attempt has been made
185+
// to load the url data before.
186+
bool m_url_load_attempted : 1;
183187
};
184188

185189
//////////

engine/src/image_rep_encoded.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ MCReferencedImageRep::MCReferencedImageRep(const char *p_file_name)
130130
{
131131
/* UNCHECKED */ MCCStringClone(p_file_name, m_file_name);
132132
m_url_data = nil;
133+
134+
// MW-2013-09-25: [[ Bug 10983 ]] No load has yet been attempted.
135+
m_url_load_attempted = false;
133136
}
134137

135138
MCReferencedImageRep::~MCReferencedImageRep()
@@ -143,20 +146,23 @@ bool MCReferencedImageRep::GetDataStream(IO_handle &r_stream)
143146
IO_handle t_stream = nil;
144147
if (MCSecureModeCanAccessDisk())
145148
t_stream = MCS_open(m_file_name, IO_READ_MODE, false, false, 0);
146-
147-
if (t_stream == nil)
149+
150+
// MW-2013-09-25: [[ Bug 10983 ]] Only ever try to load the rep as a url once.
151+
if (t_stream == nil && !m_url_load_attempted)
148152
{
149-
if (m_url_data == nil)
150-
{
151-
MCExecPoint ep(MCdefaultstackptr, nil, nil);
152-
ep.setsvalue(m_file_name);
153-
MCU_geturl(ep);
154-
if (ep.getsvalue().getlength() == 0)
155-
return false;
156-
157-
/* UNCHECKED */ MCMemoryAllocateCopy(ep.getsvalue().getstring(), ep.getsvalue().getlength(), m_url_data);
158-
m_url_data_size = ep.getsvalue().getlength();
159-
}
153+
// MW-2013-09-25: [[ Bug 10983 ]] Mark the rep has having attempted url load.
154+
m_url_load_attempted = true;
155+
156+
MCExecPoint ep(MCdefaultstackptr, nil, nil);
157+
ep.setsvalue(m_file_name);
158+
159+
MCU_geturl(ep);
160+
161+
if (ep.getsvalue().getlength() == 0)
162+
return false;
163+
164+
/* UNCHECKED */ MCMemoryAllocateCopy(ep.getsvalue().getstring(), ep.getsvalue().getlength(), m_url_data);
165+
m_url_data_size = ep.getsvalue().getlength();
160166

161167
t_stream = MCS_fakeopen(MCString((char*)m_url_data, m_url_data_size));
162168
}

engine/src/util.cpp

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,43 +2296,72 @@ void MCU_dofunc(Functions func, uint4 &nparams, real8 &n,
22962296
}
22972297
}
22982298

2299+
// MW-2013-06-25: [[ Bug 10983 ]] This function returns true if the given string
2300+
// could be a url. It checks for strings of the form:
2301+
// <letter> (<letter> | <digit> | '+' | '.' | '-')+ ':' <char>+
2302+
static bool could_be_url(const char *p_url, uint4 p_length)
2303+
{
2304+
// If the first char isn't a letter, then we are done.
2305+
if (p_length == 0 || !isalpha(p_url[0]))
2306+
return false;
2307+
2308+
uint4 t_colon_index;
2309+
for(t_colon_index = 0; t_colon_index < p_length; t_colon_index++)
2310+
{
2311+
char t_char;
2312+
t_char = p_url[t_colon_index];
2313+
2314+
// If we find the ':' we are done (end of scheme).
2315+
if (p_url[t_colon_index] == ':')
2316+
break;
2317+
2318+
// If the character isn't something allowed in a scheme name, we are done.
2319+
if (!isalpha(t_char) && !isdigit(t_char) && t_char != '+' && t_char != '.' && t_char != '-')
2320+
return false;
2321+
}
2322+
2323+
// If the scheme name < 2 chars, or there is nothing after it, we are done.
2324+
if (t_colon_index < 2 || t_colon_index + 1 == p_length)
2325+
return false;
2326+
2327+
// If we get here then we could well have a url.
2328+
return true;
2329+
}
22992330

23002331
void MCU_geturl(MCExecPoint &ep)
23012332
{
2302-
if (ep.getsvalue().getlength() > 5
2303-
&& !MCU_strncasecmp(ep.getsvalue().getstring(), "file:", 5))
2333+
if (ep.getsvalue().getlength() > 5 &&
2334+
!MCU_strncasecmp(ep.getsvalue().getstring(), "file:", 5))
23042335
{
23052336
ep.tail(5);
23062337
MCS_loadfile(ep, False);
23072338
}
2339+
else if (ep.getsvalue().getlength() > 8 &&
2340+
!MCU_strncasecmp(ep.getsvalue().getstring(), "binfile:", 8))
2341+
{
2342+
ep.tail(8);
2343+
MCS_loadfile(ep, True);
2344+
}
2345+
else if (ep.getsvalue().getlength() > 8 &&
2346+
!MCU_strncasecmp(ep.getsvalue().getstring(), "resfile:", 8))
2347+
{
2348+
ep.tail(8);
2349+
MCS_loadresfile(ep);
2350+
}
23082351
else
2309-
if (ep.getsvalue().getlength() > 8
2310-
&& !MCU_strncasecmp(ep.getsvalue().getstring(), "binfile:", 8))
2352+
{
2353+
// MW-2013-06-25: [[ Bug 10983 ]] Take more care to check if we do in fact
2354+
// have something that could be a url.
2355+
const char *sptr = ep.getsvalue().getstring();
2356+
uint4 l = ep.getsvalue().getlength();
2357+
if (could_be_url(sptr, l))
23112358
{
2312-
ep.tail(8);
2313-
MCS_loadfile(ep, True);
2359+
MCS_geturl(ep . getobj(), ep . getcstring());
2360+
MCurlresult->fetch(ep);
23142361
}
23152362
else
2316-
if (ep.getsvalue().getlength() > 8
2317-
&& !MCU_strncasecmp(ep.getsvalue().getstring(), "resfile:", 8))
2318-
{
2319-
ep.tail(8);
2320-
MCS_loadresfile(ep);
2321-
}
2322-
else
2323-
{
2324-
// MW-2013-03-12: [[ Bug 10731 ]] Make sure that if we aren't looking at something
2325-
// that looks like a URL, we clear the EP.
2326-
const char *sptr = ep.getsvalue().getstring();
2327-
uint4 l = ep.getsvalue().getlength();
2328-
if (sptr != NULL && sptr[1] != ':' && MCU_strchr(sptr, l, ':'))
2329-
{
2330-
MCS_geturl(ep . getobj(), ep . getcstring());
2331-
MCurlresult->fetch(ep);
2332-
}
2333-
else
2334-
ep . clear();
2335-
}
2363+
ep . clear();
2364+
}
23362365
}
23372366

23382367

0 commit comments

Comments
 (0)