mFile = (char*) malloc(dirlen + len);
mFile = (char*) PR_Malloc(dirlen + len);
nsresult URLImpl::ParseURL(const nsIURL* aURL, const nsString& aSpec){  // XXX hack!  char* cSpec = aSpec.ToNewCString();  const char* uProtocol = nsnull;  const char* uHost = nsnull;  const char* uFile = nsnull;  PRInt32 uPort = -1;  if (nsnull != aURL) {    uProtocol = aURL->GetProtocol();    uHost = aURL->GetHost();    uFile = aURL->GetFile();    uPort = aURL->GetPort();  }  mProtocol = nsnull;  mHost = nsnull;  mFile = nsnull;  mRef = nsnull;  mPort = -1;  mSpec = nsnull;  if (nsnull == cSpec) {    delete cSpec;    if (nsnull == aURL) {      delete cSpec;      return NS_ERROR_ILLEGAL_VALUE;    }    mProtocol = (nsnull != uProtocol) ? PL_strdup(uProtocol) : nsnull;    mHost = (nsnull != uHost) ? PL_strdup(uHost) : nsnull;    mPort = uPort;    mFile = (nsnull != uFile) ? PL_strdup(uFile) : nsnull;    delete cSpec;    return NS_OK;  }  mSpec = PL_strdup(cSpec);  const char* cp = PL_strchr(cSpec, ':');  if (nsnull == cp) {    // relative spec    if (nsnull == aURL) {      delete cSpec;      return NS_ERROR_ILLEGAL_VALUE;    }    // keep protocol and host    mProtocol = (nsnull != uProtocol) ? PL_strdup(uProtocol) : nsnull;    mHost = (nsnull != uHost) ? PL_strdup(uHost) : nsnull;    mPort = uPort;    // figure out file name    PRInt32 len = PL_strlen(cSpec) + 1;    if ((len > 1) && (cSpec[0] == '/')) {      // Relative spec is absolute to the server      mFile = PL_strdup(cSpec);    } else {      char* dp = PL_strrchr(uFile, '/');      PRInt32 dirlen = (dp + 1) - uFile;      mFile = (char*) malloc(dirlen + len);      PL_strncpy(mFile, uFile, dirlen);      PL_strcpy(mFile + dirlen, cSpec);    }  } else {    // absolute spec    // get protocol first    PRInt32 plen = cp - cSpec;    mProtocol = (char*) malloc(plen + 1);    PL_strncpy(mProtocol, cSpec, plen);    mProtocol[plen] = 0;    cp++;                               // eat : in protocol    // skip over one, two or three slashes    if (*cp == '/') {      cp++;      if (*cp == '/') {        cp++;        if (*cp == '/') {          cp++;        }      }    } else {      delete cSpec;      return NS_ERROR_ILLEGAL_VALUE;    }    const char* cp0 = cp;    if ((PL_strcmp(mProtocol, "resource") == 0) ||        (PL_strcmp(mProtocol, "file") == 0)) {      // resource/file url's do not have host names.      // The remainder of the string is the file name      PRInt32 flen = PL_strlen(cp);      mFile = (char*) malloc(flen + 1);      PL_strcpy(mFile, cp);      #ifdef NS_WIN32      if (PL_strcmp(mProtocol, "file") == 0) {        // If the filename starts with a "x|" where is an single        // character then we assume it's a drive name and change the        // vertical bar back to a ":"        if ((flen >= 2) && (mFile[1] == '|')) {          mFile[1] = ':';        }      }#endif    } else {      // Host name follows protocol for http style urls      cp = PL_strchr(cp, '/');      if (nsnull == cp) {        // There is no file name, only a host name        PRInt32 hlen = PL_strlen(cp0);        mHost = (char*) malloc(hlen + 1);        PL_strcpy(mHost, cp0);        // Set filename to "/"        mFile = (char*) malloc(2);        mFile[0] = '/';        mFile[1] = 0;      }      else {        PRInt32 hlen = cp - cp0;        mHost = (char*) malloc(hlen + 1);        PL_strncpy(mHost, cp0, hlen);        mHost[hlen] = 0;        // The rest is the file name        PRInt32 flen = PL_strlen(cp);        mFile = (char*) malloc(flen + 1);        PL_strcpy(mFile, cp);      }    }  }//printf("protocol='%s' host='%s' file='%s'\n", mProtocol, mHost, mFile);  delete cSpec;  return NS_OK;}