Update the behavior of uninitialized and NULL BMimeType objects.

* Two uninitialized BMimeType objects are considered to be equal,
  this is a purposeful break from BeOS R5.

* An uninitialized BMimeType object is considered to be equal to a
  BMimeType object initialized to NULL. This is a purposeful break from
  BeOS R5.

* Update the doxygen documentation comments to reflect this change which
  will hopefully make there way into the Haiku Book at some point.

* In BMimeType::SetTo() replace an instance of strcpy() with strlcpy()
  CID #something probably.

* Store the result of a few more strlen() function in size_t instead of
  int to prevent overflow bugs.

* Make sure BMimeType::GetSupertype() returns either B_OK or B_BAD_VALUE.

* Undo my previous "optimization" in IsValid() to declare ch outside the
  for loop.
This commit is contained in:
John Scipione
2012-03-15 14:44:00 -04:00
parent 6da8db2786
commit 84bfb380c3
+35 -27
View File
@@ -119,21 +119,24 @@ BMimeType::~BMimeType()
Nevertheless it is a very bad idea to use another supertype. Nevertheless it is a very bad idea to use another supertype.
The supplied MIME string is copied; the caller retains the ownership. The supplied MIME string is copied; the caller retains the ownership.
\param mimeType The MIME string. \param mimeType The MIME string.
\return \returns A status code.
- \c B_OK: Everything went fine. \retval B_OK Everything went fine.
- \c B_BAD_VALUE: \c NULL or invalid \a mimeString. \retval B_NO_INIT \c NULL \a mimeType string.
- \c B_NO_MEMORY: Insufficient memory to copy the MIME string. \retval B_BAD_VALUE Invalid \a mimeType string.
\retval B_NO_MEMORY Insufficient memory to copy the MIME string.
*/ */
status_t status_t
BMimeType::SetTo(const char *mimeType) BMimeType::SetTo(const char *mimeType)
{ {
if (!mimeType || !BMimeType::IsValid(mimeType)) { if (mimeType == NULL) {
Unset();
} else if (!BMimeType::IsValid(mimeType)) {
fCStatus = B_BAD_VALUE; fCStatus = B_BAD_VALUE;
} else { } else {
Unset(); Unset();
fType = new(std::nothrow) char[strlen(mimeType) + 1]; fType = new(std::nothrow) char[strlen(mimeType) + 1];
if (fType) { if (fType) {
strcpy(fType, mimeType); strlcpy(fType, mimeType, B_MIME_TYPE_LENGTH);
fCStatus = B_OK; fCStatus = B_OK;
} else { } else {
fCStatus = B_NO_MEMORY; fCStatus = B_NO_MEMORY;
@@ -199,8 +202,8 @@ BMimeType::IsSupertypeOnly() const
if (fCStatus == B_OK) { if (fCStatus == B_OK) {
// We assume here fCStatus will be B_OK *only* if // We assume here fCStatus will be B_OK *only* if
// the MIME string is valid // the MIME string is valid
int len = strlen(fType); size_t len = strlen(fType);
for (int i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
if (fType[i] == '/') if (fType[i] == '/')
return false; return false;
} }
@@ -225,47 +228,51 @@ BMimeType::IsInstalled() const
} }
// GetSupertype // GetSupertype
/*! \brief Returns the supertype of the MIME type represented by this object. /*! \brief Gets the supertype of the MIME type represented by this object.
The supplied object is initialized to this object's supertype. If this The supplied object is initialized to this object's supertype. If this
BMimeType is not properly initialized, the supplied object will be Unset(). BMimeType is not properly initialized, the supplied object will be Unset().
\param superType A pointer to the BMimeType object that shall be \param superType A pointer to the BMimeType object that shall be
initialized to this object's supertype. initialized to this object's supertype.
\return \returns A status code.
- \c B_OK: Everything went fine. \retval B_OK Everything went fine.
- \c B_BAD_VALUE: \c NULL \a superType, this object is not initialized, \retval B_BAD_VALUE \c NULL \a superType, this object is not initialized,
or this object <i> is </i> a supertype. or this object is a supertype only.
*/ */
status_t status_t
BMimeType::GetSupertype(BMimeType *superType) const BMimeType::GetSupertype(BMimeType *superType) const
{ {
if (!superType) if (superType == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
superType->Unset();
status_t err = (fCStatus == B_OK ? B_OK : B_BAD_VALUE); superType->Unset();
if (!err) { status_t status = fCStatus == B_OK ? B_OK : B_BAD_VALUE;
int len = strlen(fType); if (status == B_OK) {
int i; size_t len = strlen(fType);
for (i = 0; i < len; i++) { size_t i = 0;
for (; i < len; i++) {
if (fType[i] == '/') if (fType[i] == '/')
break; break;
} }
if (i == len) if (i == len) {
err = B_BAD_VALUE; // IsSupertypeOnly() == true // object is a supertype only
else { status = B_BAD_VALUE;
} else {
char superMime[B_MIME_TYPE_LENGTH]; char superMime[B_MIME_TYPE_LENGTH];
strncpy(superMime, fType, i); strncpy(superMime, fType, i);
superMime[i] = 0; superMime[i] = 0;
err = superType->SetTo(superMime); status = superType->SetTo(superMime) == B_OK ? B_OK : B_BAD_VALUE;
} }
} }
return err;
return status;
} }
// == // ==
/*! \brief Returns whether this and the supplied MIME type are equal. /*! \brief Returns whether this and the supplied MIME type are equal.
Two BMimeType objects are said to be equal if they represent the same Two BMimeType objects are said to be equal if they represent the same
MIME string, ignoring case, or if both are not initialized. MIME string, ignoring case, or if both are not initialized.
\warning In BeOS R5 two uninitialized BMimeType objects were not
considered to be equal, in Haiku they are.
\param type The BMimeType to be compared with. \param type The BMimeType to be compared with.
\return \c true, if the objects are equal, \c false otherwise. \return \c true, if the objects are equal, \c false otherwise.
*/ */
@@ -285,6 +292,8 @@ BMimeType::operator==(const BMimeType &type) const
A BMimeType objects equals a MIME string, if its MIME string equals the A BMimeType objects equals a MIME string, if its MIME string equals the
latter one, ignoring case, or if it is uninitialized and the MIME string latter one, ignoring case, or if it is uninitialized and the MIME string
is \c NULL. is \c NULL.
\warning In BeOS R5 an uninitialized BMimeType object was not
considered to be equal to \c NULL, in Haiku it is.
\param type The MIME string to be compared with. \param type The MIME string to be compared with.
\return \c true, if the MIME types are equal, \c false otherwise. \return \c true, if the MIME types are equal, \c false otherwise.
*/ */
@@ -1130,9 +1139,8 @@ BMimeType::IsValid(const char *string)
if (len >= B_MIME_TYPE_LENGTH || len == 0) if (len >= B_MIME_TYPE_LENGTH || len == 0)
return false; return false;
char ch;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
ch = string[i]; char ch = string[i];
if (ch == '/') { if (ch == '/') {
if (foundSlash || i == 0 || i == len - 1) if (foundSlash || i == 0 || i == len - 1)
return false; return false;