Do not throw exception for normal code flow (exceptions::no_such_parameter).
This commit is contained in:
parent
96077ce7e6
commit
7aebeeb2e2
16
src/body.cpp
16
src/body.cpp
@ -166,11 +166,11 @@ void body::parseImpl
|
|||||||
{
|
{
|
||||||
isMultipart = true;
|
isMultipart = true;
|
||||||
|
|
||||||
try
|
if (ctf->hasBoundary())
|
||||||
{
|
{
|
||||||
boundary = ctf->getBoundary();
|
boundary = ctf->getBoundary();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_parameter&)
|
else
|
||||||
{
|
{
|
||||||
// No "boundary" parameter specified: we can try to
|
// No "boundary" parameter specified: we can try to
|
||||||
// guess it by scanning the body contents...
|
// guess it by scanning the body contents...
|
||||||
@ -436,11 +436,11 @@ void body::generateImpl
|
|||||||
|
|
||||||
if (ctf)
|
if (ctf)
|
||||||
{
|
{
|
||||||
try
|
if (ctf->hasBoundary())
|
||||||
{
|
{
|
||||||
boundary = ctf->getBoundary();
|
boundary = ctf->getBoundary();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_parameter&)
|
else
|
||||||
{
|
{
|
||||||
// No boundary string specified
|
// No boundary string specified
|
||||||
boundary = generateRandomBoundaryString();
|
boundary = generateRandomBoundaryString();
|
||||||
@ -701,11 +701,11 @@ const charset body::getCharset() const
|
|||||||
|
|
||||||
if (ctf)
|
if (ctf)
|
||||||
{
|
{
|
||||||
try
|
if (ctf->hasCharset())
|
||||||
{
|
{
|
||||||
return (ctf->getCharset());
|
return (ctf->getCharset());
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_parameter&)
|
else
|
||||||
{
|
{
|
||||||
// Defaults to "us-ascii" (RFC-1521)
|
// Defaults to "us-ascii" (RFC-1521)
|
||||||
return (vmime::charset(charsets::US_ASCII));
|
return (vmime::charset(charsets::US_ASCII));
|
||||||
@ -885,14 +885,14 @@ void body::initNewPart(shared_ptr <bodyPart> part)
|
|||||||
|
|
||||||
if (ctf)
|
if (ctf)
|
||||||
{
|
{
|
||||||
try
|
if (ctf->hasBoundary())
|
||||||
{
|
{
|
||||||
const string boundary = ctf->getBoundary();
|
const string boundary = ctf->getBoundary();
|
||||||
|
|
||||||
if (boundary.empty() || !isValidBoundary(boundary))
|
if (boundary.empty() || !isValidBoundary(boundary))
|
||||||
ctf->setBoundary(generateRandomBoundaryString());
|
ctf->setBoundary(generateRandomBoundaryString());
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_parameter&)
|
else
|
||||||
{
|
{
|
||||||
// No "boundary" parameter: generate a random one.
|
// No "boundary" parameter: generate a random one.
|
||||||
ctf->setBoundary(generateRandomBoundaryString());
|
ctf->setBoundary(generateRandomBoundaryString());
|
||||||
|
@ -58,44 +58,21 @@ const word bodyPartAttachment::getName() const
|
|||||||
// Try the 'filename' parameter of 'Content-Disposition' field
|
// Try the 'filename' parameter of 'Content-Disposition' field
|
||||||
shared_ptr <const contentDispositionField> cdf = getContentDisposition();
|
shared_ptr <const contentDispositionField> cdf = getContentDisposition();
|
||||||
|
|
||||||
if (cdf)
|
if (cdf && cdf->hasFilename())
|
||||||
{
|
{
|
||||||
try
|
name = cdf->getFilename();
|
||||||
{
|
|
||||||
name = cdf->getFilename();
|
|
||||||
}
|
|
||||||
catch (exceptions::no_such_parameter&)
|
|
||||||
{
|
|
||||||
// No 'filename' parameter
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// No 'Content-Disposition' field
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try the 'name' parameter of 'Content-Type' field
|
// Try the 'name' parameter of 'Content-Type' field
|
||||||
if (name.getBuffer().empty())
|
else
|
||||||
{
|
{
|
||||||
shared_ptr <const contentTypeField> ctf = getContentType();
|
shared_ptr <const contentTypeField> ctf = getContentType();
|
||||||
|
|
||||||
if (ctf)
|
if (ctf)
|
||||||
{
|
{
|
||||||
try
|
shared_ptr <const parameter> prm = ctf->findParameter("name");
|
||||||
{
|
|
||||||
shared_ptr <const parameter> prm = ctf->findParameter("name");
|
|
||||||
|
|
||||||
if (prm != NULL)
|
if (prm != NULL)
|
||||||
name = prm->getValue();
|
name = prm->getValue();
|
||||||
}
|
|
||||||
catch (exceptions::no_such_parameter&)
|
|
||||||
{
|
|
||||||
// No attachment name available
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// No 'Content-Type' field
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,9 +40,20 @@ contentDispositionField::contentDispositionField(contentDispositionField&)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentDispositionField::hasCreationDate() const
|
||||||
|
{
|
||||||
|
return findParameter("creation-date");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const datetime contentDispositionField::getCreationDate() const
|
const datetime contentDispositionField::getCreationDate() const
|
||||||
{
|
{
|
||||||
return findParameter("creation-date")->getValueAs <datetime>();
|
shared_ptr <parameter> param = findParameter("creation-date");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValueAs <datetime>();
|
||||||
|
else
|
||||||
|
return datetime::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -52,9 +63,20 @@ void contentDispositionField::setCreationDate(const datetime& creationDate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentDispositionField::hasModificationDate() const
|
||||||
|
{
|
||||||
|
return findParameter("modification-date");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const datetime contentDispositionField::getModificationDate() const
|
const datetime contentDispositionField::getModificationDate() const
|
||||||
{
|
{
|
||||||
return findParameter("modification-date")->getValueAs <datetime>();
|
shared_ptr <parameter> param = findParameter("modification-date");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValueAs <datetime>();
|
||||||
|
else
|
||||||
|
return datetime::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,9 +86,20 @@ void contentDispositionField::setModificationDate(const datetime& modificationDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentDispositionField::hasReadDate() const
|
||||||
|
{
|
||||||
|
return findParameter("read-date");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const datetime contentDispositionField::getReadDate() const
|
const datetime contentDispositionField::getReadDate() const
|
||||||
{
|
{
|
||||||
return findParameter("read-date")->getValueAs <datetime>();
|
shared_ptr <parameter> param = findParameter("read-date");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValueAs <datetime>();
|
||||||
|
else
|
||||||
|
return datetime::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -76,9 +109,20 @@ void contentDispositionField::setReadDate(const datetime& readDate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentDispositionField::hasFilename() const
|
||||||
|
{
|
||||||
|
return findParameter("filename");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const word contentDispositionField::getFilename() const
|
const word contentDispositionField::getFilename() const
|
||||||
{
|
{
|
||||||
return findParameter("filename")->getValue();
|
shared_ptr <parameter> param = findParameter("filename");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValue();
|
||||||
|
else
|
||||||
|
return word();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,9 +132,20 @@ void contentDispositionField::setFilename(const word& filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentDispositionField::hasSize() const
|
||||||
|
{
|
||||||
|
return findParameter("size");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentDispositionField::getSize() const
|
const string contentDispositionField::getSize() const
|
||||||
{
|
{
|
||||||
return findParameter("size")->getValue().getBuffer();
|
shared_ptr <parameter> param = findParameter("size");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValue().getBuffer();
|
||||||
|
else
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,9 +40,20 @@ contentTypeField::contentTypeField(contentTypeField&)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentTypeField::hasBoundary() const
|
||||||
|
{
|
||||||
|
return findParameter("boundary");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentTypeField::getBoundary() const
|
const string contentTypeField::getBoundary() const
|
||||||
{
|
{
|
||||||
return findParameter("boundary")->getValue().getBuffer();
|
shared_ptr <parameter> param = findParameter("boundary");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValue().getBuffer();
|
||||||
|
else
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -52,9 +63,20 @@ void contentTypeField::setBoundary(const string& boundary)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentTypeField::hasCharset() const
|
||||||
|
{
|
||||||
|
return findParameter("charset");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const charset contentTypeField::getCharset() const
|
const charset contentTypeField::getCharset() const
|
||||||
{
|
{
|
||||||
return findParameter("charset")->getValueAs <charset>();
|
shared_ptr <parameter> param = findParameter("charset");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValueAs <charset>();
|
||||||
|
else
|
||||||
|
return charset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,9 +86,20 @@ void contentTypeField::setCharset(const charset& ch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool contentTypeField::hasReportType() const
|
||||||
|
{
|
||||||
|
return findParameter("report-type");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentTypeField::getReportType() const
|
const string contentTypeField::getReportType() const
|
||||||
{
|
{
|
||||||
return findParameter("report-type")->getValue().getBuffer();
|
shared_ptr <parameter> param = findParameter("report-type");
|
||||||
|
|
||||||
|
if (param)
|
||||||
|
return param->getValue().getBuffer();
|
||||||
|
else
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,21 +198,10 @@ void htmlTextPart::parse(shared_ptr <const bodyPart> message, shared_ptr <const
|
|||||||
shared_ptr <const contentTypeField> ctf =
|
shared_ptr <const contentTypeField> ctf =
|
||||||
textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||||
|
|
||||||
if (ctf)
|
if (ctf && ctf->hasCharset())
|
||||||
{
|
m_charset = ctf->getCharset();
|
||||||
try
|
|
||||||
{
|
|
||||||
m_charset = ctf->getCharset();
|
|
||||||
}
|
|
||||||
catch (exceptions::no_such_parameter)
|
|
||||||
{
|
|
||||||
// No "charset" parameter.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
m_charset = charset();
|
||||||
// No "Content-type" field.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract embedded objects. The algorithm is quite simple: for each previously
|
// Extract embedded objects. The algorithm is quite simple: for each previously
|
||||||
// found inline part, we check if its CID/Location is contained in the HTML text.
|
// found inline part, we check if its CID/Location is contained in the HTML text.
|
||||||
|
@ -407,14 +407,10 @@ shared_ptr <parameter> parameterizedHeaderField::findParameter(const string& par
|
|||||||
|
|
||||||
// No parameter with this name can be found
|
// No parameter with this name can be found
|
||||||
if (pos == end)
|
if (pos == end)
|
||||||
{
|
return null;
|
||||||
throw exceptions::no_such_parameter(paramName);
|
|
||||||
}
|
|
||||||
// Else, return a reference to the existing parameter
|
// Else, return a reference to the existing parameter
|
||||||
else
|
return (*pos);
|
||||||
{
|
|
||||||
return (*pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,21 +78,10 @@ void plainTextPart::parse(shared_ptr <const bodyPart> /* message */,
|
|||||||
shared_ptr <const contentTypeField> ctf =
|
shared_ptr <const contentTypeField> ctf =
|
||||||
textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||||
|
|
||||||
if (ctf)
|
if (ctf && ctf->hasCharset())
|
||||||
{
|
m_charset = ctf->getCharset();
|
||||||
try
|
|
||||||
{
|
|
||||||
m_charset = ctf->getCharset();
|
|
||||||
}
|
|
||||||
catch (exceptions::no_such_parameter&)
|
|
||||||
{
|
|
||||||
// No "charset" parameter.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
m_charset = charset();
|
||||||
// No "Content-type" field.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,9 @@ namespace vmime
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/** Describes presentation information, as per RFC-2183.
|
||||||
|
*/
|
||||||
|
|
||||||
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField
|
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField
|
||||||
{
|
{
|
||||||
friend class headerFieldFactory;
|
friend class headerFieldFactory;
|
||||||
@ -47,10 +50,15 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Test whether the "creation-date" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "creation-date" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasCreationDate() const;
|
||||||
|
|
||||||
/** Return the value of the "creation-date" parameter.
|
/** Return the value of the "creation-date" parameter.
|
||||||
*
|
*
|
||||||
* @return value of the "creation-date" parameter
|
* @return value of the "creation-date" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const datetime getCreationDate() const;
|
const datetime getCreationDate() const;
|
||||||
|
|
||||||
@ -60,10 +68,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setCreationDate(const datetime& creationDate);
|
void setCreationDate(const datetime& creationDate);
|
||||||
|
|
||||||
|
/** Test whether the "modification-date" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "modification-date" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasModificationDate() const;
|
||||||
|
|
||||||
/** Return the value of the "modification-date" parameter.
|
/** Return the value of the "modification-date" parameter.
|
||||||
*
|
*
|
||||||
* @return value of the "modification-date" parameter
|
* @return value of the "modification-date" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const datetime getModificationDate() const;
|
const datetime getModificationDate() const;
|
||||||
|
|
||||||
@ -73,10 +86,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setModificationDate(const datetime& modificationDate);
|
void setModificationDate(const datetime& modificationDate);
|
||||||
|
|
||||||
|
/** Test whether the "read-date" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "read-date" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasReadDate() const;
|
||||||
|
|
||||||
/** Return the value of the "read-date" parameter.
|
/** Return the value of the "read-date" parameter.
|
||||||
*
|
*
|
||||||
* @return value of the "read-date" parameter
|
* @return value of the "read-date" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const datetime getReadDate() const;
|
const datetime getReadDate() const;
|
||||||
|
|
||||||
@ -86,10 +104,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setReadDate(const datetime& readDate);
|
void setReadDate(const datetime& readDate);
|
||||||
|
|
||||||
|
/** Test whether the "filename" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "filename" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasFilename() const;
|
||||||
|
|
||||||
/** Return the value of the "filename" parameter.
|
/** Return the value of the "filename" parameter.
|
||||||
*
|
*
|
||||||
* @return value of the "filename" parameter
|
* @return value of the "filename" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const word getFilename() const;
|
const word getFilename() const;
|
||||||
|
|
||||||
@ -99,10 +122,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setFilename(const word& filename);
|
void setFilename(const word& filename);
|
||||||
|
|
||||||
|
/** Test whether the "size" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "size" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasSize() const;
|
||||||
|
|
||||||
/** Return the value of the "size" parameter.
|
/** Return the value of the "size" parameter.
|
||||||
*
|
*
|
||||||
* @return value of the "size" parameter
|
* @return value of the "size" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const string getSize() const;
|
const string getSize() const;
|
||||||
|
|
||||||
|
@ -46,11 +46,16 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Test whether the "boundary" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "boundary" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasBoundary() const;
|
||||||
|
|
||||||
/** Return the value of the "boundary" parameter. Boundary is a
|
/** Return the value of the "boundary" parameter. Boundary is a
|
||||||
* random string used to separate body parts.
|
* random string used to separate body parts.
|
||||||
*
|
*
|
||||||
* @return value of the "boundary" parameter
|
* @return value of the "boundary" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const string getBoundary() const;
|
const string getBoundary() const;
|
||||||
|
|
||||||
@ -63,11 +68,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setBoundary(const string& boundary);
|
void setBoundary(const string& boundary);
|
||||||
|
|
||||||
|
/** Test whether the "charset" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "charset" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasCharset() const;
|
||||||
|
|
||||||
/** Return the value of the "charset" parameter. It specifies the
|
/** Return the value of the "charset" parameter. It specifies the
|
||||||
* charset used in the body part contents.
|
* charset used in the body part contents.
|
||||||
*
|
*
|
||||||
* @return value of the "charset" parameter
|
* @return value of the "charset" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const charset getCharset() const;
|
const charset getCharset() const;
|
||||||
|
|
||||||
@ -78,10 +88,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setCharset(const charset& ch);
|
void setCharset(const charset& ch);
|
||||||
|
|
||||||
|
/** Test whether the "report-type" parameter is set.
|
||||||
|
*
|
||||||
|
* @return true if the "report-type" parameter is set, or false otherwise
|
||||||
|
*/
|
||||||
|
bool hasReportType() const;
|
||||||
|
|
||||||
/** Return the value of the "report-type" parameter (RFC-1892).
|
/** Return the value of the "report-type" parameter (RFC-1892).
|
||||||
*
|
*
|
||||||
* @return value of the "report-type" parameter
|
* @return value of the "report-type" parameter
|
||||||
* @throw exceptions::no_such_parameter if the parameter does not exist
|
|
||||||
*/
|
*/
|
||||||
const string getReportType() const;
|
const string getReportType() const;
|
||||||
|
|
||||||
|
@ -64,10 +64,11 @@ public:
|
|||||||
bool hasParameter(const string& paramName) const;
|
bool hasParameter(const string& paramName) const;
|
||||||
|
|
||||||
/** Find the first parameter that matches the specified name.
|
/** Find the first parameter that matches the specified name.
|
||||||
* If no parameter is found, an exception is thrown.
|
* If no parameter is found, NULL is returned.
|
||||||
*
|
*
|
||||||
* @throw exceptions::no_such_parameter if no parameter with this name exists
|
* @param paramName parameter name
|
||||||
* @return first parameter with the specified name
|
* @return first parameter with the specified name, or NULL if
|
||||||
|
* no parameter with this name exists
|
||||||
*/
|
*/
|
||||||
shared_ptr <parameter> findParameter(const string& paramName) const;
|
shared_ptr <parameter> findParameter(const string& paramName) const;
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ public:
|
|||||||
* If no parameter is found, one will be created and inserted into
|
* If no parameter is found, one will be created and inserted into
|
||||||
* the parameter list.
|
* the parameter list.
|
||||||
*
|
*
|
||||||
|
* @param paramName parameter name
|
||||||
* @return first parameter with the specified name or a new field
|
* @return first parameter with the specified name or a new field
|
||||||
* if no parameter is found
|
* if no parameter is found
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user