Example #1
0
static int
MimeMultipartSigned_parse_line (const char *line, PRInt32 length, MimeObject *obj)
{
  MimeMultipart *mult = (MimeMultipart *) obj;
  MimeMultipartSigned *sig = (MimeMultipartSigned *) obj;
  MimeMultipartParseState old_state = mult->state;
  bool hash_line_p = true;
  bool no_headers_p = false;
  int status = 0;

  /* First do the parsing for normal multipart/ objects by handing it off to
   the superclass method.  This includes calling the create_child and
   close_child methods.
   */
  status = (((MimeObjectClass *)(&MIME_SUPERCLASS))
      ->parse_line (line, length, obj));
  if (status < 0) return status;

  /* The instance variable MimeMultipartClass->state tracks motion through
   the various stages of multipart/ parsing.  The instance variable
   MimeMultipartSigned->state tracks the difference between the first
   part (the body) and the second part (the signature.)  This second,
   more specific state variable is updated by noticing the transitions
   of the first, more general state variable.
   */
  if (old_state != mult->state)  /* there has been a state change */
  {
    switch (mult->state)
    {
    case MimeMultipartPreamble:
      PR_ASSERT(0);  /* can't move *in* to preamble state. */
      sig->state = MimeMultipartSignedPreamble;
      break;

    case MimeMultipartHeaders:
      /* If we're moving in to the Headers state, then that means
       that this line is the preceeding boundary string (and we
       should ignore it.)
       */
      hash_line_p = PR_FALSE;

      if (sig->state == MimeMultipartSignedPreamble)
      sig->state = MimeMultipartSignedBodyFirstHeader;
      else if (sig->state == MimeMultipartSignedBodyFirstLine ||
           sig->state == MimeMultipartSignedBodyLine)
      sig->state = MimeMultipartSignedSignatureHeaders;
      else if (sig->state == MimeMultipartSignedSignatureFirstLine ||
           sig->state == MimeMultipartSignedSignatureLine)
      sig->state = MimeMultipartSignedEpilogue;
      break;

    case MimeMultipartPartFirstLine:
      if (sig->state == MimeMultipartSignedBodyFirstHeader)
      {      
        sig->state = MimeMultipartSignedBodyFirstLine;
        no_headers_p = PR_TRUE;
      }
      else if (sig->state == MimeMultipartSignedBodyHeaders)
      sig->state = MimeMultipartSignedBodyFirstLine;
      else if (sig->state == MimeMultipartSignedSignatureHeaders)
      sig->state = MimeMultipartSignedSignatureFirstLine;
      else
      sig->state = MimeMultipartSignedEpilogue;
      break;

    case MimeMultipartPartLine:

      PR_ASSERT(sig->state == MimeMultipartSignedBodyFirstLine ||
          sig->state == MimeMultipartSignedBodyLine ||
          sig->state == MimeMultipartSignedSignatureFirstLine ||
          sig->state == MimeMultipartSignedSignatureLine);

      if (sig->state == MimeMultipartSignedBodyFirstLine)
      sig->state = MimeMultipartSignedBodyLine;
      else if (sig->state == MimeMultipartSignedSignatureFirstLine)
      sig->state = MimeMultipartSignedSignatureLine;
      break;

    case MimeMultipartEpilogue:
      sig->state = MimeMultipartSignedEpilogue;
      break;

    default:  /* bad state */
      NS_ERROR("bad state in MultipartSigned parse line");
      return -1;
      break;
    }
  }


  /* Perform multipart/signed-related actions on this line based on the state
   of the parser.
   */
  switch (sig->state)
  {
  case MimeMultipartSignedPreamble:
    /* Do nothing. */
    break;

  case MimeMultipartSignedBodyFirstLine:
    /* We have just moved out of the MimeMultipartSignedBodyHeaders
     state, so cache away the headers that apply only to the body part.
     */
    NS_ASSERTION(mult->hdrs, "null multipart hdrs");
    NS_ASSERTION(!sig->body_hdrs, "signed part shouldn't have already have body_hdrs");
    sig->body_hdrs = mult->hdrs;
    mult->hdrs = 0;

    /* fall through. */

  case MimeMultipartSignedBodyFirstHeader:
  case MimeMultipartSignedBodyHeaders:
  case MimeMultipartSignedBodyLine:

    if (!sig->crypto_closure)
    {
      /* Set error change */
      PR_SetError(0, 0);
      /* Initialize the signature verification library. */
      sig->crypto_closure = (((MimeMultipartSignedClass *) obj->clazz)
                 ->crypto_init) (obj);
      if (!sig->crypto_closure)
      {
        status = PR_GetError();
        NS_ASSERTION(status < 0, "got non-negative status");
        if (status >= 0)
          status = -1;
        return status;
      }
    }

    if (hash_line_p)
    {
      /* this is the first hashed line if this is the first header
       (that is, if it's the first line in the header state after
       a state change.)
       */
      bool first_line_p
      = (no_headers_p ||
         sig->state == MimeMultipartSignedBodyFirstHeader);

      if (sig->state == MimeMultipartSignedBodyFirstHeader)
      sig->state = MimeMultipartSignedBodyHeaders;

      /* The newline issues here are tricky, since both the newlines
       before and after the boundary string are to be considered part
       of the boundary: this is so that a part can be specified such
       that it does not end in a trailing newline.

       To implement this, we send a newline *before* each line instead
       of after, except for the first line, which is not preceeded by a
       newline.

       For purposes of cryptographic hashing, we always hash line
       breaks as CRLF -- the canonical, on-the-wire linebreaks, since
       we have no idea of knowing what line breaks were used on the
       originating system (SMTP rightly destroys that information.)
       */

      /* Remove the trailing newline... */
      if (length > 0 && line[length-1] == '\n') length--;
      if (length > 0 && line[length-1] == '\r') length--;

      PR_ASSERT(sig->crypto_closure);

      if (!first_line_p)
      {
        /* Push out a preceeding newline... */
        char nl[] = CRLF;
        status = (((MimeMultipartSignedClass *) obj->clazz)
            ->crypto_data_hash (nl, 2, sig->crypto_closure));
        if (status < 0) return status;
      }

      /* Now push out the line sans trailing newline. */
      if (length > 0)
      status = (((MimeMultipartSignedClass *) obj->clazz)
            ->crypto_data_hash (line,length, sig->crypto_closure));
      if (status < 0) return status;
    }
    break;

  case MimeMultipartSignedSignatureHeaders:

    if (sig->crypto_closure &&
      old_state != mult->state)
    {
      /* We have just moved out of the MimeMultipartSignedBodyLine
       state, so tell the signature verification library that we've
       reached the end of the signed data.
       */
      status = (((MimeMultipartSignedClass *) obj->clazz)
          ->crypto_data_eof) (sig->crypto_closure, PR_FALSE);
      if (status < 0) return status;
    }
    break;

  case MimeMultipartSignedSignatureFirstLine:
    /* We have just moved out of the MimeMultipartSignedSignatureHeaders
     state, so cache away the headers that apply only to the sig part.
     */
    PR_ASSERT(mult->hdrs);
    PR_ASSERT(!sig->sig_hdrs);
    sig->sig_hdrs = mult->hdrs;
    mult->hdrs = 0;


    /* If the signature block has an encoding, set up a decoder for it.
     (Similar logic is in MimeLeafClass->parse_begin.)
     */
    {
    MimeDecoderData *(*fn) (nsresult (*) (const char*, PRInt32,void*), void*) = 0;
    nsCString encoding;
    encoding.Adopt(MimeHeaders_get (sig->sig_hdrs,
                   HEADER_CONTENT_TRANSFER_ENCODING,
                   PR_TRUE, PR_FALSE));
    if (encoding.IsEmpty())
      ;
    else if (!PL_strcasecmp(encoding.get(), ENCODING_BASE64))
      fn = &MimeB64DecoderInit;
    else if (!PL_strcasecmp(encoding.get(), ENCODING_QUOTED_PRINTABLE))
    {
      sig->sig_decoder_data =
  MimeQPDecoderInit (((nsresult (*) (const char *, PRInt32, void *))
     (((MimeMultipartSignedClass *) obj->clazz)
          ->crypto_signature_hash)),
    sig->crypto_closure);
      if (!sig->sig_decoder_data)
  return MIME_OUT_OF_MEMORY;
    }
    else if (!PL_strcasecmp(encoding.get(), ENCODING_UUENCODE) ||
             !PL_strcasecmp(encoding.get(), ENCODING_UUENCODE2) ||
             !PL_strcasecmp(encoding.get(), ENCODING_UUENCODE3) ||
             !PL_strcasecmp(encoding.get(), ENCODING_UUENCODE4))
      fn = &MimeUUDecoderInit;
    else if (!PL_strcasecmp(encoding.get(), ENCODING_YENCODE))
      fn = &MimeYDecoderInit;
    if (fn)
      {
      sig->sig_decoder_data =
        fn (((nsresult (*) (const char *, PRInt32, void *))
           (((MimeMultipartSignedClass *) obj->clazz)
          ->crypto_signature_hash)),
          sig->crypto_closure);
      if (!sig->sig_decoder_data)
        return MIME_OUT_OF_MEMORY;
      }
    }

    /* Show these headers to the crypto module. */
    if (hash_line_p)
    {
      status = (((MimeMultipartSignedClass *) obj->clazz)
          ->crypto_signature_init) (sig->crypto_closure,
                        obj, sig->sig_hdrs);
      if (status < 0) return status;
    }

    /* fall through. */

  case MimeMultipartSignedSignatureLine:
    if (hash_line_p)
    {
      /* Feed this line into the signature verification routines. */

      if (sig->sig_decoder_data)
      status = MimeDecoderWrite (sig->sig_decoder_data, line, length, nsnull);
      else
      status = (((MimeMultipartSignedClass *) obj->clazz)
            ->crypto_signature_hash (line, length,
                         sig->crypto_closure));
      if (status < 0) return status;
    }
    break;

  case MimeMultipartSignedEpilogue:
    /* Nothing special to do here. */
    break;

  default:  /* bad state */
    PR_ASSERT(0);
    return -1;
  }

  return status;
}
Example #2
0
void
nsThebesDeviceContext::CalcPrintingSize()
{
    if (!mPrintingSurface)
        return;

    PRBool inPoints = PR_TRUE;

    gfxSize size(0, 0);
    switch (mPrintingSurface->GetType()) {
    case gfxASurface::SurfaceTypeImage:
        inPoints = PR_FALSE;
        size = reinterpret_cast<gfxImageSurface*>(mPrintingSurface.get())->GetSize();
        break;

#if defined(MOZ_PDF_PRINTING)
    case gfxASurface::SurfaceTypePDF:
        inPoints = PR_TRUE;
        size = reinterpret_cast<gfxPDFSurface*>(mPrintingSurface.get())->GetSize();
        break;
#endif

#ifdef MOZ_ENABLE_GTK2
    case gfxASurface::SurfaceTypePS:
        inPoints = PR_TRUE;
        size = reinterpret_cast<gfxPSSurface*>(mPrintingSurface.get())->GetSize();
        break;
#endif

#ifdef XP_MACOSX
    case gfxASurface::SurfaceTypeQuartz:
        inPoints = PR_TRUE; // this is really only true when we're printing
        size = reinterpret_cast<gfxQuartzSurface*>(mPrintingSurface.get())->GetSize();
        break;
#endif

#ifdef XP_WIN
    case gfxASurface::SurfaceTypeWin32:
    case gfxASurface::SurfaceTypeWin32Printing:
    {
        inPoints = PR_FALSE;
        HDC dc =  GetPrintHDC();
        if (!dc)
            dc = GetDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET));
        size.width = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, HORZRES)/mPrintingScale, AppUnitsPerDevPixel());
        size.height = NSFloatPixelsToAppUnits(::GetDeviceCaps(dc, VERTRES)/mPrintingScale, AppUnitsPerDevPixel());
        mDepth = (PRUint32)::GetDeviceCaps(dc, BITSPIXEL);
        if (dc != (HDC)GetPrintHDC())
            ReleaseDC((HWND)mWidget->GetNativeData(NS_NATIVE_WIDGET), dc);
        break;
    }
#endif

#ifdef XP_OS2
    case gfxASurface::SurfaceTypeOS2:
    {
        inPoints = PR_FALSE;
        // we already set the size in the surface constructor we set for
        // printing, so just get those values here
        size = reinterpret_cast<gfxOS2Surface*>(mPrintingSurface.get())->GetSize();
        // as they are in pixels we need to scale them to app units
        size.width = NSFloatPixelsToAppUnits(size.width, AppUnitsPerDevPixel());
        size.height = NSFloatPixelsToAppUnits(size.height, AppUnitsPerDevPixel());
        // still need to get the depth from the device context
        HDC dc = GetPrintHDC();
        LONG value;
        if (DevQueryCaps(dc, CAPS_COLOR_BITCOUNT, 1, &value))
            mDepth = value;
        else
            mDepth = 8; // default to 8bpp, should be enough for printers
        break;
    }
#endif
    default:
        NS_ERROR("trying to print to unknown surface type");
    }

    if (inPoints) {
        // For printing, CSS inches and physical inches are identical
        // so it doesn't matter which we use here
        mWidth = NSToCoordRound(float(size.width) * AppUnitsPerPhysicalInch() / 72);
        mHeight = NSToCoordRound(float(size.height) * AppUnitsPerPhysicalInch() / 72);
    } else {
        mWidth = NSToIntRound(size.width);
        mHeight = NSToIntRound(size.height);
    }
}
extern "C" nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
{

    typedef struct {
        uint32_t hi;
        uint32_t lo;
    } DU;               // have to move 64 bit entities as 32 bit halves since
                        // stack slots are not guaranteed 16 byte aligned

#define PARAM_BUFFER_COUNT     16

    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = nullptr;
    nsIInterfaceInfo* iface_info = nullptr;
    const nsXPTMethodInfo* info;
    uint8_t paramCount;
    uint8_t i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->GetInterfaceInfo(&iface_info);
    NS_ASSERTION(iface_info,"no interface info");

    iface_info->GetMethodInfo(uint16_t(methodIndex), &info);
    NS_ASSERTION(info,"no interface info");

    paramCount = info->GetParamCount();

    // setup variant array pointer
    if(paramCount > PARAM_BUFFER_COUNT)
        dispatchParams = new nsXPTCMiniVariant[paramCount];
    else
        dispatchParams = paramBuffer;
    NS_ASSERTION(dispatchParams,"no place for params");

    uint32_t* ap = args;
    for(i = 0; i < paramCount; i++, ap++)
    {
        const nsXPTParamInfo& param = info->GetParam(i);
        const nsXPTType& type = param.GetType();
        nsXPTCMiniVariant* dp = &dispatchParams[i];

        if(param.IsOut() || !type.IsArithmetic())
        {
            dp->val.p = (void*) *ap;
            continue;
        }
        // else
        switch(type)
        {
        case nsXPTType::T_I8     : dp->val.i8  = *((int32_t*)  ap);       break;
        case nsXPTType::T_I16    : dp->val.i16 = *((int32_t*) ap);       break;
        case nsXPTType::T_I32    : dp->val.i32 = *((int32_t*) ap);       break;
        case nsXPTType::T_DOUBLE :
        case nsXPTType::T_U64    :
        case nsXPTType::T_I64    : ((DU *)dp)->hi = ((DU *)ap)->hi; 
                                   ((DU *)dp)->lo = ((DU *)ap)->lo;
                                   ap++;
                                   break;
        case nsXPTType::T_U8     : dp->val.u8  = *((uint32_t*)ap);       break;
        case nsXPTType::T_U16    : dp->val.u16 = *((uint32_t*)ap);       break;
        case nsXPTType::T_U32    : dp->val.u32 = *((uint32_t*)ap);       break;
        case nsXPTType::T_FLOAT  : dp->val.f   = *((float*)   ap);       break;
        case nsXPTType::T_BOOL   : dp->val.b   = *((uint32_t*)ap);       break;
        case nsXPTType::T_CHAR   : dp->val.c   = *((uint32_t*)ap);       break;
        case nsXPTType::T_WCHAR  : dp->val.wc  = *((int32_t*) ap);       break;
        default:
            NS_ERROR("bad type");
            break;
        }
    }

    result = self->CallMethod((uint16_t)methodIndex, info, dispatchParams);

    NS_RELEASE(iface_info);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
// for nsIRunnable.  this thread spins in ldap_result() awaiting the next
// message.  once one arrives, it dispatches it to the nsILDAPMessageListener 
// on the main thread.
//
// XXX do all returns from this function need to do thread cleanup?
//
NS_IMETHODIMP
nsLDAPConnectionLoop::Run(void)
{
    PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, 
           ("nsLDAPConnection::Run() entered\n"));

    // wait for results
    //
    while(1) {

        // Exit this thread if we no longer have an nsLDAPConnection
        // associated with it. We also aquire a lock here, to make sure
        // to avoid a possible race condition when the nsLDAPConnection
        // is destructed during the call to do_QueryReferent() (since that
        // function isn't MT safe).
        //
        nsresult rv;

        PR_Lock(mLock);
        nsCOMPtr<nsILDAPConnection> strongConn = 
            do_QueryReferent(mWeakConn, &rv);
        PR_Unlock(mLock);

        if (NS_FAILED(rv)) {
            mWeakConn = 0;
            return NS_OK;
        }
        // we use a raw connection because we need to call non-interface
        // methods
        mRawConn = static_cast<nsLDAPConnection *>(static_cast<nsILDAPConnection *>(strongConn.get()));

        // XXX deal with timeouts better
        //
        NS_ASSERTION(mRawConn->mConnectionHandle, "nsLDAPConnection::Run(): "
                     "no connection created.\n");

        // We can't enumerate over mPendingOperations itself, because the
        // callback needs to modify mPendingOperations.  So we clone it first,
        // and enumerate over the clone.  It kinda sucks that we need to do
        // this everytime we poll, but the hashtable will pretty much always
        // be small.
        //
        // only clone if the number of pending operations is non-zero
        // otherwise, put the LDAP connection thread to sleep (briefly)
        // until there is pending operations..
        if (mRawConn->mPendingOperations->Count()) {
          nsHashtable *hashtableCopy = mRawConn->mPendingOperations->Clone();
          if (hashtableCopy) {
            hashtableCopy->Enumerate(CheckLDAPOperationResult, this);
            delete hashtableCopy;
          } else {
            // punt and hope it works next time around
            NS_ERROR("nsLDAPConnectionLoop::Run() error cloning hashtable");
          }
        }
        else {
          PR_Sleep(PR_MillisecondsToInterval(40));
        }
    }

    // This will never happen, but here just in case.
    //
    return NS_OK;
}
Example #5
0
bool
BufferTextureHost::Upload(nsIntRegion *aRegion)
{
  if (!GetBuffer()) {
    // We don't have a buffer; a possible cause is that the IPDL actor
    // is already dead. This inevitably happens as IPDL actors can die
    // at any time, so we want to silently return in this case.
    return false;
  }
  if (!mCompositor) {
    NS_WARNING("Tried to upload without a compositor. Skipping texture upload...");
    // If we are in this situation it means we should have called SetCompositor
    // earlier. It is conceivable that on certain rare conditions with async-video
    // we may end up here for the first frame, but this should not happen repeatedly.
    return false;
  }
  if (mFormat == gfx::SurfaceFormat::UNKNOWN) {
    NS_WARNING("BufferTextureHost: unsupported format!");
    return false;
  } else if (mFormat == gfx::SurfaceFormat::YUV) {
    YCbCrImageDataDeserializer yuvDeserializer(GetBuffer(), GetBufferSize());
    MOZ_ASSERT(yuvDeserializer.IsValid());

    if (!mCompositor->SupportsEffect(EffectTypes::YCBCR)) {
      RefPtr<gfx::DataSourceSurface> surf = yuvDeserializer.ToDataSourceSurface();
      if (!mFirstSource) {
        mFirstSource = mCompositor->CreateDataTextureSource(mFlags);
      }
      mFirstSource->Update(surf, aRegion);
      return true;
    }

    RefPtr<DataTextureSource> srcY;
    RefPtr<DataTextureSource> srcU;
    RefPtr<DataTextureSource> srcV;
    if (!mFirstSource) {
      // We don't support BigImages for YCbCr compositing.
      srcY = mCompositor->CreateDataTextureSource(mFlags|TextureFlags::DISALLOW_BIGIMAGE);
      srcU = mCompositor->CreateDataTextureSource(mFlags|TextureFlags::DISALLOW_BIGIMAGE);
      srcV = mCompositor->CreateDataTextureSource(mFlags|TextureFlags::DISALLOW_BIGIMAGE);
      mFirstSource = srcY;
      srcY->SetNextSibling(srcU);
      srcU->SetNextSibling(srcV);
    } else {
      // mFormat never changes so if this was created as a YCbCr host and already
      // contains a source it should already have 3 sources.
      // BufferTextureHost only uses DataTextureSources so it is safe to assume
      // all 3 sources are DataTextureSource.
      MOZ_ASSERT(mFirstSource->GetNextSibling());
      MOZ_ASSERT(mFirstSource->GetNextSibling()->GetNextSibling());
      srcY = mFirstSource;
      srcU = mFirstSource->GetNextSibling()->AsDataTextureSource();
      srcV = mFirstSource->GetNextSibling()->GetNextSibling()->AsDataTextureSource();
    }


    RefPtr<gfx::DataSourceSurface> tempY =
      gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetYData(),
                                                    yuvDeserializer.GetYStride(),
                                                    yuvDeserializer.GetYSize(),
                                                    gfx::SurfaceFormat::A8);
    RefPtr<gfx::DataSourceSurface> tempCb =
      gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetCbData(),
                                                    yuvDeserializer.GetCbCrStride(),
                                                    yuvDeserializer.GetCbCrSize(),
                                                    gfx::SurfaceFormat::A8);
    RefPtr<gfx::DataSourceSurface> tempCr =
      gfx::Factory::CreateWrappingDataSourceSurface(yuvDeserializer.GetCrData(),
                                                    yuvDeserializer.GetCbCrStride(),
                                                    yuvDeserializer.GetCbCrSize(),
                                                    gfx::SurfaceFormat::A8);
    // We don't support partial updates for Y U V textures
    NS_ASSERTION(!aRegion, "Unsupported partial updates for YCbCr textures");
    if (!srcY->Update(tempY) ||
        !srcU->Update(tempCb) ||
        !srcV->Update(tempCr)) {
      NS_WARNING("failed to update the DataTextureSource");
      return false;
    }
  } else {
    // non-YCbCr case
    if (!mFirstSource) {
      mFirstSource = mCompositor->CreateDataTextureSource();
    }
    ImageDataDeserializer deserializer(GetBuffer(), GetBufferSize());
    if (!deserializer.IsValid()) {
      NS_ERROR("Failed to deserialize image!");
      return false;
    }

    RefPtr<gfx::DataSourceSurface> surf = deserializer.GetAsSurface();
    if (!surf) {
      return false;
    }

    if (!mFirstSource->Update(surf.get(), aRegion)) {
      NS_WARNING("failed to update the DataTextureSource");
      return false;
    }
  }
  return true;
}
Example #6
0
nsresult
AppleVTDecoder::InitializeSession()
{
  OSStatus rv;

#ifdef LOG_MEDIA_SHA1
  SHA1Sum avc_hash;
  avc_hash.update(mConfig.extra_data->Elements(), mConfig.extra_data->Length());
  uint8_t digest_buf[SHA1Sum::kHashSize];
  avc_hash.finish(digest_buf);
  nsAutoCString avc_digest;
  for (size_t i = 0; i < sizeof(digest_buf); i++) {
    avc_digest.AppendPrintf("%02x", digest_buf[i]);
  }
  LOG("AVCDecoderConfig %ld bytes sha1 %s",
      mConfig.extra_data->Length(), avc_digest.get());
#endif // LOG_MEDIA_SHA1

  AutoCFRelease<CFDictionaryRef> extensions = CreateDecoderExtensions();

  rv = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
                                      kCMVideoCodecType_H264,
                                      mPictureWidth,
                                      mPictureHeight,
                                      extensions,
                                      &mFormat);
  if (rv != noErr) {
    NS_ERROR("Couldn't create format description!");
    return NS_ERROR_FAILURE;
  }

  // Contruct video decoder selection spec.
  AutoCFRelease<CFDictionaryRef> spec = CreateDecoderSpecification();

  // Contruct output configuration.
  AutoCFRelease<CFDictionaryRef> outputConfiguration =
    CreateOutputConfiguration();

  VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this };
  rv = VTDecompressionSessionCreate(kCFAllocatorDefault,
                                    mFormat,
                                    spec, // Video decoder selection.
                                    outputConfiguration, // Output video format.
                                    &cb,
                                    &mSession);

  if (rv != noErr) {
    NS_ERROR("Couldn't create decompression session!");
    return NS_ERROR_FAILURE;
  }

  if (AppleVTLinker::skPropUsingHWAccel) {
    CFBooleanRef isUsingHW = nullptr;
    rv = VTSessionCopyProperty(mSession,
                               AppleVTLinker::skPropUsingHWAccel,
                               kCFAllocatorDefault,
                               &isUsingHW);
    if (rv != noErr) {
      LOG("AppleVTDecoder: system doesn't support hardware acceleration");
    }
    LOG("AppleVTDecoder: %s hardware accelerated decoding",
        (rv == noErr && isUsingHW == kCFBooleanTrue) ? "using" : "not using");
  } else {
    LOG("AppleVTDecoder: couldn't determine hardware acceleration status.");
  }
  return NS_OK;
}
nsresult
nsLDAPConnection::InvokeMessageCallback(LDAPMessage *aMsgHandle, 
                                        nsILDAPMessage *aMsg,
                                        PRBool aRemoveOpFromConnQ)
{
    PRInt32 msgId;
    nsresult rv;
    nsCOMPtr<nsILDAPOperation> operation;
    nsCOMPtr<nsILDAPMessageListener> listener;

#if defined(DEBUG)
    // We only want this being logged for debug builds so as not to affect performance too much.
    PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, ("InvokeMessageCallback entered\n"));
#endif

    // get the message id corresponding to this operation
    //
    msgId = ldap_msgid(aMsgHandle);
    if (msgId == -1) {
        NS_ERROR("nsLDAPConnection::GetCallbackByMessage(): "
                 "ldap_msgid() failed\n");
        return NS_ERROR_FAILURE;
    }

    // get this in key form.  note that using nsVoidKey in this way assumes
    // that sizeof(void *) >= sizeof PRInt32
    //
    nsVoidKey *key = new nsVoidKey(reinterpret_cast<void *>(msgId));
    if (!key)
        return NS_ERROR_OUT_OF_MEMORY;

    // find the operation in question
    operation = getter_AddRefs(static_cast<nsILDAPOperation *>(mPendingOperations->Get(key)));
    if (!operation) {

        PR_LOG(gLDAPLogModule, PR_LOG_WARNING, 
               ("Warning: InvokeMessageCallback(): couldn't find "
                "nsILDAPOperation corresponding to this message id\n"));
        delete key;

        // this may well be ok, since it could just mean that the operation
        // was aborted while some number of messages were already in transit.
        //
        return NS_OK;
    }


    // Make sure the mOperation member is set to this operation before
    // we call the callback.
    //
    static_cast<nsLDAPMessage *>(aMsg)->mOperation = operation;

    // get the message listener object (this may be a proxy for a
    // callback which should happen on another thread)
    //
    rv = operation->GetMessageListener(getter_AddRefs(listener));
    if (NS_FAILED(rv)) {
        NS_ERROR("nsLDAPConnection::InvokeMessageCallback(): probable "
                 "memory corruption: GetMessageListener() returned error");
        delete key;
        return NS_ERROR_UNEXPECTED;
    }

    // invoke the callback 
    //
    if (listener) {
      listener->OnLDAPMessage(aMsg);
    }
    // if requested (ie the operation is done), remove the operation
    // from the connection queue.
    //
    if (aRemoveOpFromConnQ) {
        nsCOMPtr <nsLDAPOperation> operation = 
          getter_AddRefs(static_cast<nsLDAPOperation *>
                                    (mPendingOperations->Get(key)));
        // try to break cycles
        if (operation)
          operation->Clear();
        rv = mPendingOperations->Remove(key);
        if (NS_FAILED(rv)) {
            NS_ERROR("nsLDAPConnection::InvokeMessageCallback: unable to "
                     "remove operation from the connection queue\n");
            delete key;
            return NS_ERROR_UNEXPECTED;
        }

        PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, 
               ("pending operation removed; total pending operations now ="
                " %d\n", mPendingOperations->Count()));
    }

    delete key;
    return NS_OK;
}
Example #8
0
NS_IMETHODIMP
SmsParent::Observe(nsISupports* aSubject, const char* aTopic,
                   const PRUnichar* aData)
{
  if (!strcmp(aTopic, kSmsReceivedObserverTopic)) {
    MobileMessageData msgData;
    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
      NS_ERROR("Got a 'sms-received' topic without a valid message!");
      return NS_OK;
    }

    unused << SendNotifyReceivedMessage(msgData);
    return NS_OK;
  }

  if (!strcmp(aTopic, kSmsRetrievingObserverTopic)) {
    MobileMessageData msgData;
    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
      NS_ERROR("Got a 'sms-retrieving' topic without a valid message!");
      return NS_OK;
    }

    unused << SendNotifyRetrievingMessage(msgData);
    return NS_OK;
  }

  if (!strcmp(aTopic, kSmsSendingObserverTopic)) {
    MobileMessageData msgData;
    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
      NS_ERROR("Got a 'sms-sending' topic without a valid message!");
      return NS_OK;
    }

    unused << SendNotifySendingMessage(msgData);
    return NS_OK;
  }

  if (!strcmp(aTopic, kSmsSentObserverTopic)) {
    MobileMessageData msgData;
    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
      NS_ERROR("Got a 'sms-sent' topic without a valid message!");
      return NS_OK;
    }

    unused << SendNotifySentMessage(msgData);
    return NS_OK;
  }

  if (!strcmp(aTopic, kSmsFailedObserverTopic)) {
    MobileMessageData msgData;
    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
      NS_ERROR("Got a 'sms-failed' topic without a valid message!");
      return NS_OK;
    }

    unused << SendNotifyFailedMessage(msgData);
    return NS_OK;
  }

  if (!strcmp(aTopic, kSmsDeliverySuccessObserverTopic)) {
    MobileMessageData msgData;
    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
      NS_ERROR("Got a 'sms-sending' topic without a valid message!");
      return NS_OK;
    }

    unused << SendNotifyDeliverySuccessMessage(msgData);
    return NS_OK;
  }

  if (!strcmp(aTopic, kSmsDeliveryErrorObserverTopic)) {
    MobileMessageData msgData;
    if (!GetMobileMessageDataFromMessage(aSubject, msgData)) {
      NS_ERROR("Got a 'sms-delivery-error' topic without a valid message!");
      return NS_OK;
    }

    unused << SendNotifyDeliveryErrorMessage(msgData);
    return NS_OK;
  }

  if (!strcmp(aTopic, kSilentSmsReceivedObserverTopic)) {
    nsCOMPtr<nsIDOMMozSmsMessage> smsMsg = do_QueryInterface(aSubject);
    if (!smsMsg) {
      return NS_OK;
    }

    nsString sender;
    if (NS_FAILED(smsMsg->GetSender(sender)) ||
        !mSilentNumbers.Contains(sender)) {
      return NS_OK;
    }

    MobileMessageData msgData =
      static_cast<SmsMessage*>(smsMsg.get())->GetData();
    unused << SendNotifyReceivedSilentMessage(msgData);
    return NS_OK;
  }

  return NS_OK;
}
nsHtml5Parser::SetParserFilter(nsIParserFilter* aFilter)
{
  NS_ERROR("Attempt to set a parser filter on HTML5 parser.");
}
Example #10
0
// static
XPCWrappedNativeProto*
XPCWrappedNativeProto::GetNewOrUsed(XPCCallContext& ccx,
                                    XPCWrappedNativeScope* Scope,
                                    nsIClassInfo* ClassInfo,
                                    const XPCNativeScriptableCreateInfo* ScriptableCreateInfo,
                                    JSBool ForceNoSharing,
                                    JSBool isGlobal,
                                    QITableEntry* offsets)
{
    NS_ASSERTION(Scope, "bad param");
    NS_ASSERTION(ClassInfo, "bad param");

    AutoMarkingWrappedNativeProtoPtr proto(ccx);
    ClassInfo2WrappedNativeProtoMap* map;
    XPCLock* lock;
    JSBool shared;

    JSUint32 ciFlags;
    if(NS_FAILED(ClassInfo->GetFlags(&ciFlags)))
        ciFlags = 0;

    if(ciFlags & XPC_PROTO_DONT_SHARE)
    {
        NS_ERROR("reserved flag set!");
        ciFlags &= ~XPC_PROTO_DONT_SHARE;
    }

    if(ForceNoSharing || (ciFlags & nsIClassInfo::PLUGIN_OBJECT) ||
       (ScriptableCreateInfo &&
        ScriptableCreateInfo->GetFlags().DontSharePrototype()))
    {
        ciFlags |= XPC_PROTO_DONT_SHARE;
        shared = JS_FALSE;
    }
    else
    {
        shared = JS_TRUE;
    }

    if(shared)
    {
        map = Scope->GetWrappedNativeProtoMap();
        lock = Scope->GetRuntime()->GetMapLock();
        {   // scoped lock
            XPCAutoLock al(lock);
            proto = map->Find(ClassInfo);
            if(proto)
                return proto;
        }
    }

    AutoMarkingNativeSetPtr set(ccx);
    set = XPCNativeSet::GetNewOrUsed(ccx, ClassInfo);
    if(!set)
        return nsnull;

    proto = new XPCWrappedNativeProto(Scope, ClassInfo, ciFlags, set, offsets);

    if(!proto || !proto->Init(ccx, isGlobal, ScriptableCreateInfo))
    {
        delete proto.get();
        return nsnull;
    }

    if(shared)
    {   // scoped lock
        XPCAutoLock al(lock);
        map->Add(ClassInfo, proto);
    }

    return proto;
}
Example #11
0
TiledLayerBufferComposite::TiledLayerBufferComposite(ISurfaceAllocator* aAllocator,
                                                     const SurfaceDescriptorTiles& aDescriptor,
                                                     const nsIntRegion& aOldPaintedRegion,
                                                     Compositor* aCompositor)
{
  mIsValid = true;
  mHasDoubleBufferedTiles = false;
  mValidRegion = aDescriptor.validRegion();
  mPaintedRegion = aDescriptor.paintedRegion();
  mRetainedWidth = aDescriptor.retainedWidth();
  mRetainedHeight = aDescriptor.retainedHeight();
  mResolution = aDescriptor.resolution();
  mFrameResolution = CSSToParentLayerScale(aDescriptor.frameResolution());
  if (mResolution == 0 || IsNaN(mResolution)) {
    // There are divisions by mResolution so this protects the compositor process
    // against malicious content processes and fuzzing.
    mIsValid = false;
    return;
  }

  // Combine any valid content that wasn't already uploaded
  nsIntRegion oldPaintedRegion(aOldPaintedRegion);
  oldPaintedRegion.And(oldPaintedRegion, mValidRegion);
  mPaintedRegion.Or(mPaintedRegion, oldPaintedRegion);

  bool isSameProcess = aAllocator->IsSameProcess();

  const InfallibleTArray<TileDescriptor>& tiles = aDescriptor.tiles();
  for(size_t i = 0; i < tiles.Length(); i++) {
    CompositableTextureHostRef texture;
    CompositableTextureHostRef textureOnWhite;
    const TileDescriptor& tileDesc = tiles[i];
    switch (tileDesc.type()) {
      case TileDescriptor::TTexturedTileDescriptor : {
        texture = TextureHost::AsTextureHost(tileDesc.get_TexturedTileDescriptor().textureParent());
        MaybeTexture onWhite = tileDesc.get_TexturedTileDescriptor().textureOnWhite();
        if (onWhite.type() == MaybeTexture::TPTextureParent) {
          textureOnWhite = TextureHost::AsTextureHost(onWhite.get_PTextureParent());
        }
        const TileLock& ipcLock = tileDesc.get_TexturedTileDescriptor().sharedLock();
        nsRefPtr<gfxSharedReadLock> sharedLock;
        if (ipcLock.type() == TileLock::TShmemSection) {
          sharedLock = gfxShmSharedReadLock::Open(aAllocator, ipcLock.get_ShmemSection());
        } else {
          if (!isSameProcess) {
            // Trying to use a memory based lock instead of a shmem based one in
            // the cross-process case is a bad security violation.
            NS_ERROR("A client process may be trying to peek at the host's address space!");
            // This tells the TiledContentHost that deserialization failed so that
            // it can propagate the error.
            mIsValid = false;

            mRetainedTiles.Clear();
            return;
          }
          sharedLock = reinterpret_cast<gfxMemorySharedReadLock*>(ipcLock.get_uintptr_t());
          if (sharedLock) {
            // The corresponding AddRef is in TiledClient::GetTileDescriptor
            sharedLock.get()->Release();
          }
        }

        CompositableTextureSourceRef textureSource;
        CompositableTextureSourceRef textureSourceOnWhite;
        if (texture) {
          texture->SetCompositor(aCompositor);
          texture->PrepareTextureSource(textureSource);
        }
        if (textureOnWhite) {
          textureOnWhite->SetCompositor(aCompositor);
          textureOnWhite->PrepareTextureSource(textureSourceOnWhite);
        }
        mRetainedTiles.AppendElement(TileHost(sharedLock,
                                              texture.get(),
                                              textureOnWhite.get(),
                                              textureSource.get(),
                                              textureSourceOnWhite.get()));
        break;
      }
      default:
        NS_WARNING("Unrecognised tile descriptor type");
        // Fall through
      case TileDescriptor::TPlaceholderTileDescriptor :
        mRetainedTiles.AppendElement(GetPlaceholderTile());
        break;
    }
    if (texture && !texture->HasInternalBuffer()) {
      mHasDoubleBufferedTiles = true;
    }
  }
}
static nsresult
buildASN1ObjectFromDER(unsigned char *data,
                       unsigned char *end,
                       nsIASN1Sequence *parent)
{
  nsresult rv;
  nsCOMPtr<nsIASN1Sequence> sequence;
  nsCOMPtr<nsIASN1PrintableItem> printableItem;
  nsCOMPtr<nsIASN1Object> asn1Obj;
  nsCOMPtr<nsIMutableArray> parentObjects;

  NS_ENSURE_ARG_POINTER(parent);
  if (data >= end)
    return NS_OK;

  unsigned char code, tagnum;

  // A DER item has the form of |tag|len|data
  // tag is one byte and describes the type of elment
  //     we are dealing with.
  // len is a DER encoded int telling us how long the data is
  // data is a buffer that is len bytes long and has to be
  //      interpreted according to its type.
  unsigned long bytesUsed;
  bool indefinite;
  PRInt32 len;
  PRUint32 type;

  rv = parent->GetASN1Objects(getter_AddRefs(parentObjects));
  if (NS_FAILED(rv) || parentObjects == nsnull)
    return NS_ERROR_FAILURE;
  while (data < end) {
    code = *data;
    tagnum = code & SEC_ASN1_TAGNUM_MASK;

    /*
     * NOTE: This code does not (yet) handle the high-tag-number form!
     */
    if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
      return NS_ERROR_FAILURE;
    }
    data++;
    len = getDERItemLength(data, end, &bytesUsed, &indefinite);
    data += bytesUsed;
    if ((len < 0) || ((data+len) > end))
      return NS_ERROR_FAILURE;

    if (code & SEC_ASN1_CONSTRUCTED) {
      if (len > 0 || indefinite) {
        sequence = new nsNSSASN1Sequence();
        switch (code & SEC_ASN1_CLASS_MASK) {
        case SEC_ASN1_UNIVERSAL:
          type = tagnum;
          break;
        case SEC_ASN1_APPLICATION:
          type = nsIASN1Object::ASN1_APPLICATION;
          break;
        case SEC_ASN1_CONTEXT_SPECIFIC:
          type = nsIASN1Object::ASN1_CONTEXT_SPECIFIC;
          break;
        case SEC_ASN1_PRIVATE:
          type = nsIASN1Object::ASN1_PRIVATE;
          break;
        default:
          NS_ERROR("Bad DER");
          return NS_ERROR_FAILURE;
        }
        sequence->SetTag(tagnum);
        sequence->SetType(type);
        rv = buildASN1ObjectFromDER(data, (len == 0) ? end : data + len, 
                                    sequence);
        asn1Obj = sequence;
      }
    } else {
      printableItem = new nsNSSASN1PrintableItem();

      asn1Obj = printableItem;
      asn1Obj->SetType(tagnum);
      asn1Obj->SetTag(tagnum); 
      printableItem->SetData((char*)data, len);
    }
    data += len;
    parentObjects->AppendElement(asn1Obj, false);
  }

  return NS_OK;
}
Example #13
0
bool
PluginProcessChild::Init()
{
    nsDebugImpl::SetMultiprocessMode("NPAPI");

#if defined(XP_MACOSX)
    // Remove the trigger for "dyld interposing" that we added in
    // GeckoChildProcessHost::PerformAsyncLaunchInternal(), in the host
    // process just before we were launched.  Dyld interposing will still
    // happen in our process (the plugin child process).  But we don't want
    // it to happen in any processes that the plugin might launch from our
    // process.
    nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES"));
    if (!interpose.IsEmpty()) {
        // If we added the path to libplugin_child_interpose.dylib to an
        // existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a
        // ":" path seperator.
        int32_t lastSeparatorPos = interpose.RFind(":");
        int32_t lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib");
        bool needsReset = false;
        if (lastTriggerPos != -1) {
            if (lastSeparatorPos == -1) {
                interpose.Truncate();
                needsReset = true;
            } else if (lastTriggerPos > lastSeparatorPos) {
                interpose.SetLength(lastSeparatorPos);
                needsReset = true;
            }
        }
        if (needsReset) {
            nsCString setInterpose("DYLD_INSERT_LIBRARIES=");
            if (!interpose.IsEmpty()) {
                setInterpose.Append(interpose);
            }
            // Values passed to PR_SetEnv() must be seperately allocated.
            char* setInterposePtr = strdup(setInterpose.get());
            PR_SetEnv(setInterposePtr);
        }
    }
#endif

#ifdef XP_WIN
    // Drag-and-drop needs OleInitialize to be called, and Silverlight depends
    // on the host calling CoInitialize (which is called by OleInitialize).
    ::OleInitialize(nullptr);
#endif

    // Certain plugins, such as flash, steal the unhandled exception filter
    // thus we never get crash reports when they fault. This call fixes it.
    message_loop()->set_exception_restoration(true);

    std::string pluginFilename;

#if defined(OS_POSIX)
    // NB: need to be very careful in ensuring that the first arg
    // (after the binary name) here is indeed the plugin module path.
    // Keep in sync with dom/plugins/PluginModuleParent.
    std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
    MOZ_ASSERT(values.size() >= 2, "not enough args");

    pluginFilename = UnmungePluginDsoPath(values[1]);

#elif defined(OS_WIN)
    std::vector<std::wstring> values =
        CommandLine::ForCurrentProcess()->GetLooseValues();
    MOZ_ASSERT(values.size() >= 1, "not enough loose args");

    if (ShouldProtectPluginCurrentDirectory(values[0].c_str())) {
        SanitizeEnvironmentVariables();
        SetDllDirectory(L"");
    }

    pluginFilename = WideToUTF8(values[0]);

#if defined(MOZ_SANDBOX)
    // This is probably the earliest we would want to start the sandbox.
    // As we attempt to tighten the sandbox, we may need to consider moving this
    // to later in the plugin initialization.
    mozilla::SandboxTarget::Instance()->StartSandbox();
#endif
#else
#  error Sorry
#endif

    if (NS_FAILED(nsRegion::InitStatic())) {
      NS_ERROR("Could not initialize nsRegion");
      return false;
    }

    bool retval = mPlugin.InitForChrome(pluginFilename, ParentPid(),
                                        IOThreadChild::message_loop(),
                                        IOThreadChild::channel());
#if defined(XP_MACOSX)
    if (nsCocoaFeatures::OnYosemiteOrLater()) {
      // Explicitly turn off CGEvent logging.  This works around bug 1092855.
      // If there are already CGEvents in the log, turning off logging also
      // causes those events to be written to disk.  But at this point no
      // CGEvents have yet been processed.  CGEvents are events (usually
      // input events) pulled from the WindowServer.  An option of 0x80000008
      // turns on CGEvent logging.
      CGSSetDebugOptions(0x80000007);
    }
#endif
    return retval;
}
Example #14
0
static int
MimeMultipartSigned_parse_child_line (MimeObject *obj,
                    const char *line, PRInt32 length,
                    bool first_line_p)
{
  MimeMultipartSigned *sig = (MimeMultipartSigned *) obj;
  MimeContainer *cont = (MimeContainer *) obj;
  int status = 0;

  /* Shouldn't have made any sub-parts yet. */
  PR_ASSERT(cont->nchildren == 0);
  if (cont->nchildren != 0) return -1;

  switch (sig->state)
  {
  case MimeMultipartSignedPreamble:
  case MimeMultipartSignedBodyFirstHeader:
  case MimeMultipartSignedBodyHeaders:
    // How'd we get here?  Oh well, fall through.
    NS_ERROR("wrong state in parse child line");

  case MimeMultipartSignedBodyFirstLine:
    PR_ASSERT(first_line_p);
    if (!sig->part_buffer)
    {
      sig->part_buffer = MimePartBufferCreate();
      if (!sig->part_buffer)
      return MIME_OUT_OF_MEMORY;
    }
    /* fall through */

  case MimeMultipartSignedBodyLine:
    {
    /* This is the first part; we are buffering it, and will emit it all
       at the end (so that we know whether the signature matches before
       showing anything to the user.)
     */

    /* The newline issues here are tricky, since both the newlines
       before and after the boundary string are to be considered part
       of the boundary: this is so that a part can be specified such
       that it does not end in a trailing newline.

       To implement this, we send a newline *before* each line instead
       of after, except for the first line, which is not preceeded by a
       newline.
     */

    /* Remove the trailing newline... */
    if (length > 0 && line[length-1] == '\n') length--;
    if (length > 0 && line[length-1] == '\r') length--;

    PR_ASSERT(sig->part_buffer);
    PR_ASSERT(first_line_p ==
          (sig->state == MimeMultipartSignedBodyFirstLine));

    if (!first_line_p)
      {
      /* Push out a preceeding newline... */
      char nl[] = MSG_LINEBREAK;
      status = MimePartBufferWrite (sig->part_buffer, nl, MSG_LINEBREAK_LEN);
      if (status < 0) return status;
      }

    /* Now push out the line sans trailing newline. */
    if (length > 0)
      status = MimePartBufferWrite (sig->part_buffer, line, length);
    if (status < 0) return status;
    }
  break;

  case MimeMultipartSignedSignatureHeaders:
    // How'd we get here?  Oh well, fall through.
    NS_ERROR("should have already parse sig hdrs");

  case MimeMultipartSignedSignatureFirstLine:
  case MimeMultipartSignedSignatureLine:
    /* Nothing to do here -- hashing of the signature part is handled up
     in MimeMultipartSigned_parse_line().
     */
    break;

  case MimeMultipartSignedEpilogue:
    /* Too many kids?  MimeMultipartSigned_create_child() should have
     prevented us from getting here. */
    NS_ERROR("too many kids?");
    return -1;
    break;

  default: /* bad state */
    NS_ERROR("bad state in multipart signed parse line");
    return -1;
    break;
  }

  return status;
}
    static nsresult
    PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
    {
#define PARAM_BUFFER_COUNT     16

        nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
        nsXPTCMiniVariant* dispatchParams = nullptr;
        nsIInterfaceInfo* iface_info = nullptr;
        const nsXPTMethodInfo* info;
        uint8_t paramCount;
        uint8_t i;
        nsresult result = NS_ERROR_FAILURE;

        NS_ASSERTION(self,"no self");

        self->GetInterfaceInfo(&iface_info);
        NS_ASSERTION(iface_info,"no interface info");

        iface_info->GetMethodInfo(uint16_t(methodIndex), &info);
        NS_ASSERTION(info,"no interface info");

        paramCount = info->GetParamCount();

        // setup variant array pointer
        if(paramCount > PARAM_BUFFER_COUNT)
            dispatchParams = new nsXPTCMiniVariant[paramCount];
        else
            dispatchParams = paramBuffer;
        NS_ASSERTION(dispatchParams,"no place for params");

        uint32_t* ap = args;
        for(i = 0; i < paramCount; i++, ap++)
        {
            const nsXPTParamInfo& param = info->GetParam(i);
            const nsXPTType& type = param.GetType();
            nsXPTCMiniVariant* dp = &dispatchParams[i];

            if(param.IsOut() || !type.IsArithmetic())
            {
                dp->val.p = (void*) *ap;
                continue;
            }

            switch(type)
            {
            // the 8 and 16 bit types will have been promoted to 32 bits before
            // being pushed onto the stack. Since the 68k is big endian, we
            // need to skip over the leading high order bytes.
            case nsXPTType::T_I8     : dp->val.i8  = *(((int8_t*) ap) + 3);  break;
            case nsXPTType::T_I16    : dp->val.i16 = *(((int16_t*) ap) + 1); break;
            case nsXPTType::T_I32    : dp->val.i32 = *((int32_t*) ap);       break;
            case nsXPTType::T_I64    : dp->val.i64 = *((int64_t*) ap); ap++; break;
            case nsXPTType::T_U8     : dp->val.u8  = *(((uint8_t*) ap) + 3); break;
            case nsXPTType::T_U16    : dp->val.u16 = *(((uint16_t*)ap) + 1); break;
            case nsXPTType::T_U32    : dp->val.u32 = *((uint32_t*)ap);       break;
            case nsXPTType::T_U64    : dp->val.u64 = *((uint64_t*)ap); ap++; break;
            case nsXPTType::T_FLOAT  : dp->val.f   = *((float*)   ap);       break;
            case nsXPTType::T_DOUBLE : dp->val.d   = *((double*)  ap); ap++; break;
            case nsXPTType::T_BOOL   : dp->val.b   = *(((char*)   ap) + 3);  break;
            case nsXPTType::T_CHAR   : dp->val.c   = *(((char*)   ap) + 3);  break;
            // wchar_t is an int (32 bits) on NetBSD
            case nsXPTType::T_WCHAR  : dp->val.wc  = *((wchar_t*) ap);       break;
            default:
                NS_ERROR("bad type");
                break;
            }
        }

        result = self->CallMethod((uint16_t)methodIndex, info, dispatchParams);

        NS_RELEASE(iface_info);

        if(dispatchParams != paramBuffer)
            delete [] dispatchParams;

        return result;
    }
extern "C" nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase* self,
                   uint32_t methodIndex,
                   uint32_t* args,
                   uint32_t *gprData,
                   double *fprData)
{
    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    nsIInterfaceInfo* iface_info = NULL;
    const nsXPTMethodInfo* info;
    uint32_t paramCount;
    uint32_t i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->GetInterfaceInfo(&iface_info);
    NS_ASSERTION(iface_info,"no interface info");
    if (! iface_info)
        return NS_ERROR_UNEXPECTED;

    iface_info->GetMethodInfo(uint16_t(methodIndex), &info);
    NS_ASSERTION(info,"no method info");
    if (! info)
        return NS_ERROR_UNEXPECTED;

    paramCount = info->GetParamCount();

    // setup variant array pointer
    if(paramCount > PARAM_BUFFER_COUNT)
        dispatchParams = new nsXPTCMiniVariant[paramCount];
    else
        dispatchParams = paramBuffer;

    NS_ASSERTION(dispatchParams,"no place for params");
    if (! dispatchParams)
        return NS_ERROR_OUT_OF_MEMORY;

    uint32_t* ap = args;
    uint32_t gpr = 1;    // skip one GPR register
    uint32_t fpr = 0;
    uint32_t tempu32;
    uint64_t tempu64;

    for(i = 0; i < paramCount; i++) {
        const nsXPTParamInfo& param = info->GetParam(i);
        const nsXPTType& type = param.GetType();
        nsXPTCMiniVariant* dp = &dispatchParams[i];
	
        if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
            if (fpr < FPR_COUNT)
                dp->val.d = fprData[fpr++];
            else {
                if ((uint32_t) ap & 4) ap++; // doubles are 8-byte aligned on stack
                dp->val.d = *(double*) ap;
                ap += 2;
		if (gpr < GPR_COUNT)
		    gpr += 2;
            }
            continue;
        }
        else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
            if (fpr < FPR_COUNT)
                dp->val.f = (float) fprData[fpr++]; // in registers floats are passed as doubles
            else {
                dp->val.f = *(float*) ap;
		ap += 1;
		if (gpr < GPR_COUNT)
		    gpr += 1;
            }
            continue;
        }
        else if (!param.IsOut() && (type == nsXPTType::T_I64
                                    || type == nsXPTType::T_U64)) {
            if (gpr & 1) gpr++; // longlongs are aligned in odd/even register pairs, eg. r5/r6
            if ((gpr + 1) < GPR_COUNT) {
                tempu64 = *(uint64_t*) &gprData[gpr];
                gpr += 2;
            }
            else {
                if ((uint32_t) ap & 4) ap++; // longlongs are 8-byte aligned on stack
                tempu64 = *(uint64_t*) ap;
                ap += 2;
            }
        }
        else {
            if (gpr < GPR_COUNT)
                tempu32 = gprData[gpr++];
            else
                tempu32 = *ap++;
        }

        if(param.IsOut() || !type.IsArithmetic()) {
            dp->val.p = (void*) tempu32;
            continue;
        }

        switch(type) {
        case nsXPTType::T_I8:      dp->val.i8  = (int8_t)   tempu32; break;
        case nsXPTType::T_I16:     dp->val.i16 = (int16_t)  tempu32; break;
        case nsXPTType::T_I32:     dp->val.i32 = (int32_t)  tempu32; break;
        case nsXPTType::T_I64:     dp->val.i64 = (int64_t)  tempu64; break;
        case nsXPTType::T_U8:      dp->val.u8  = (uint8_t)  tempu32; break;
        case nsXPTType::T_U16:     dp->val.u16 = (uint16_t) tempu32; break;
        case nsXPTType::T_U32:     dp->val.u32 = (uint32_t) tempu32; break;
        case nsXPTType::T_U64:     dp->val.u64 = (uint64_t) tempu64; break;
        case nsXPTType::T_BOOL:    dp->val.b   = (bool)   tempu32; break;
        case nsXPTType::T_CHAR:    dp->val.c   = (char)     tempu32; break;
        case nsXPTType::T_WCHAR:   dp->val.wc  = (wchar_t)  tempu32; break;

        default:
            NS_ERROR("bad type");
            break;
        }
    }

    result = self->CallMethod((uint16_t) methodIndex, info, dispatchParams);

    NS_RELEASE(iface_info);

    if (dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
Example #17
0
void
CanvasLayerD3D10::Initialize(const Data& aData)
{
  NS_ASSERTION(mSurface == nullptr, "BasicCanvasLayer::Initialize called twice!");

  if (aData.mGLContext) {
    mGLContext = aData.mGLContext;
    NS_ASSERTION(mGLContext->IsOffscreen(), "Canvas GLContext must be offscreen.");
    mDataIsPremultiplied = aData.mIsGLAlphaPremult;
    mNeedsYFlip = true;

    GLScreenBuffer* screen = mGLContext->Screen();
    SurfaceStreamType streamType =
        SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
                                          screen->PreserveBuffer());

    SurfaceFactory_GL* factory = nullptr;
    if (!gfxPrefs::WebGLForceLayersReadback()) {
      if (mGLContext->IsANGLE()) {
        factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext,
                                                          device(),
                                                          screen->Caps());
      }
    }

    if (factory) {
      screen->Morph(factory, streamType);
    }
  } else if (aData.mDrawTarget) {
    mDrawTarget = aData.mDrawTarget;
    mNeedsYFlip = false;
    mDataIsPremultiplied = true;
    void *texture = mDrawTarget->GetNativeSurface(NativeSurfaceType::D3D10_TEXTURE);

    if (texture) {
      mTexture = static_cast<ID3D10Texture2D*>(texture);

      NS_ASSERTION(!aData.mGLContext,
                   "CanvasLayer can't have both DrawTarget and WebGLContext/Surface");

      mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
      device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRView));
      return;
    }

    // XXX we should store mDrawTarget and use it directly in UpdateSurface,
    // bypassing Thebes
    mSurface = mDrawTarget->Snapshot();
  } else {
    NS_ERROR("CanvasLayer created without mSurface, mDrawTarget or mGLContext?");
  }

  mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
  mIsD2DTexture = false;

  // Create a texture in case we need to readback.
  CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, mBounds.width, mBounds.height, 1, 1);
  desc.Usage = D3D10_USAGE_DYNAMIC;
  desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;

  HRESULT hr = device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(mTexture));
  if (FAILED(hr)) {
    NS_WARNING("Failed to create texture for CanvasLayer!");
    return;
  }

  device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mUploadSRView));
}
Example #18
0
/**
 * Called to layout our our children. Does no frame construction
 */
NS_IMETHODIMP
nsListBoxLayout::LayoutInternal(nsIFrame* aBox, nsBoxLayoutState& aState)
{
  int32_t redrawStart = -1;

  // Get the start y position.
  nsListBoxBodyFrame* body = static_cast<nsListBoxBodyFrame*>(aBox);
  if (!body) {
    NS_ERROR("Frame encountered that isn't a listboxbody!");
    return NS_ERROR_FAILURE;
  }

  nsMargin margin;

  // Get our client rect.
  nsRect clientRect;
  aBox->GetClientRect(clientRect);

  // Get the starting y position and the remaining available
  // height.
  nscoord availableHeight = body->GetAvailableHeight();
  nscoord yOffset = body->GetYPosition();
  
  if (availableHeight <= 0) {
    bool fixed = (body->GetFixedRowSize() != -1);
    if (fixed)
      availableHeight = 10;
    else
      return NS_OK;
  }

  // run through all our currently created children
  nsIFrame* box = body->GetChildBox();

  // if the reason is resize or initial we must relayout.
  nscoord rowHeight = body->GetRowHeightAppUnits();

  while (box) {
    // If this box is dirty or if it has dirty children, we
    // call layout on it.
    nsRect childRect(box->GetRect());
    box->GetMargin(margin);
    
    // relayout if we must or we are dirty or some of our children are dirty
    //   or the client area is wider than us
    // XXXldb There should probably be a resize check here too!
    if (NS_SUBTREE_DIRTY(box) || childRect.width < clientRect.width) {
      childRect.x = 0;
      childRect.y = yOffset;
      childRect.width = clientRect.width;
      
      nsSize size = box->GetPrefSize(aState);
      body->SetRowHeight(size.height);
      
      childRect.height = rowHeight;

      childRect.Deflate(margin);
      box->SetBounds(aState, childRect);
      box->Layout(aState);
    } else {
      // if the child did not need to be relayed out. Then its easy.
      // Place the child by just grabbing its rect and adjusting the y.
      int32_t newPos = yOffset+margin.top;

      // are we pushing down or pulling up any rows?
      // Then we may have to redraw everything below the moved 
      // rows.
      if (redrawStart == -1 && childRect.y != newPos)
        redrawStart = newPos;

      childRect.y = newPos;
      box->SetBounds(aState, childRect);
    }

    // Ok now the available size gets smaller and we move the
    // starting position of the next child down some.
    nscoord size = childRect.height + margin.top + margin.bottom;

    yOffset += size;
    availableHeight -= size;
    
    box = box->GetNextBox();
  }
  
  // We have enough available height left to add some more rows
  // Since we can't do this during layout, we post a callback
  // that will be processed after the reflow completes.
  body->PostReflowCallback();
    
  // if rows were pushed down or pulled up because some rows were added
  // before them then redraw everything under the inserted rows. The inserted
  // rows will automatically be redrawn because the were marked dirty on insertion.
  if (redrawStart > -1) {
    aBox->Redraw(aState);
  }

  return NS_OK;
}
NS_IMETHODIMP
nsLDAPConnection::Init(nsILDAPURL *aUrl, const nsACString &aBindName,
                       nsILDAPMessageListener *aMessageListener,
                       nsISupports *aClosure, PRUint32 aVersion)
{
  NS_ENSURE_ARG_POINTER(aUrl);
  NS_ENSURE_ARG_POINTER(aMessageListener);

  // Save various items that we'll use later
  mBindName.Assign(aBindName);
  mClosure = aClosure;
  mInitListener = aMessageListener;

  // Make sure we haven't called Init earlier, i.e. there's a DNS
  // request pending.
  NS_ASSERTION(!mDNSRequest, "nsLDAPConnection::Init() "
               "Connection was already initialized\n");

  // Check and save the version number
  if (aVersion != nsILDAPConnection::VERSION2 && 
      aVersion != nsILDAPConnection::VERSION3) {
    NS_ERROR("nsLDAPConnection::Init(): illegal version");
    return NS_ERROR_ILLEGAL_VALUE;
  }
  mVersion = aVersion;

  nsresult rv;

  // Get the port number, SSL flag for use later, once the DNS server(s)
  // has resolved the host part.
  rv = aUrl->GetPort(&mPort);
  NS_ENSURE_SUCCESS(rv, rv);

  PRUint32 options;
  rv = aUrl->GetOptions(&options);
  NS_ENSURE_SUCCESS(rv, rv);

  mSSL = options & nsILDAPURL::OPT_SECURE;

  // allocate a hashtable to keep track of pending operations.
  // 10 buckets seems like a reasonable size, and we do want it to 
  // be threadsafe
  mPendingOperations = new nsSupportsHashtable(10, PR_TRUE);
  if (!mPendingOperations) {
    NS_ERROR("failure initializing mPendingOperations hashtable");
    return NS_ERROR_OUT_OF_MEMORY;
  }

  nsCOMPtr<nsIThread> curThread = do_GetCurrentThread();
  if (!curThread) {
    NS_ERROR("nsLDAPConnection::Init(): couldn't get current thread");
    return NS_ERROR_FAILURE;
  }

  // Do the pre-resolve of the hostname, using the DNS service. This
  // will also initialize the LDAP connection properly, once we have
  // the IPs resolved for the hostname. This includes creating the
  // new thread for this connection.
  //
  // XXX - What return codes can we expect from the DNS service?
  //
  nsCOMPtr<nsIDNSService> 
    pDNSService(do_GetService(kDNSServiceContractId, &rv));

  if (NS_FAILED(rv)) {
    NS_ERROR("nsLDAPConnection::Init(): couldn't create the DNS Service object");
    return NS_ERROR_FAILURE;
  }

  rv = aUrl->GetAsciiHost(mDNSHost);
  NS_ENSURE_SUCCESS(rv, rv);

  // if the caller has passed in a space-delimited set of hosts, as the 
  // ldap c-sdk allows, strip off the trailing hosts for now.
  // Soon, we'd like to make multiple hosts work, but now make
  // at least the first one work.
  mDNSHost.CompressWhitespace(PR_TRUE, PR_TRUE);

  PRInt32 spacePos = mDNSHost.FindChar(' ');
  // trim off trailing host(s)
  if (spacePos != kNotFound)
    mDNSHost.Truncate(spacePos);

  rv = pDNSService->AsyncResolve(mDNSHost, 0, this, curThread, 
                                 getter_AddRefs(mDNSRequest));

  if (NS_FAILED(rv)) {
    switch (rv) {
    case NS_ERROR_OUT_OF_MEMORY:
    case NS_ERROR_UNKNOWN_HOST:
    case NS_ERROR_FAILURE:
    case NS_ERROR_OFFLINE:
      break;

    default:
      rv = NS_ERROR_UNEXPECTED;
    }
    mDNSHost.Truncate();
  }
  return rv;
}
NS_IMETHODIMP
nsAutoCompleteController::HandleText()
{
  if (!mInput) {
    // Stop all searches in case they are async.
    StopSearch();
    // Note: if now is after blur and IME end composition,
    // check mInput before calling.
    // See https://bugzilla.mozilla.org/show_bug.cgi?id=193544#c31
    NS_ERROR("Called before attaching to the control or after detaching from the control");
    return NS_OK;
  }

  nsAutoString newValue;
  nsCOMPtr<nsIAutoCompleteInput> input(mInput);
  input->GetTextValue(newValue);

  // Note: the events occur in the following order when IME is used.
  // 1. composition start event(HandleStartComposition)
  // 2. composition end event(HandleEndComposition)
  // 3. input event(HandleText)
  // Note that the input event occurs if IME composition is cancelled, as well.
  // In HandleEndComposition, we are processing the popup properly.
  // Therefore, the input event after composition end event should do nothing.
  // (E.g., calling StopSearch() and ClosePopup().)
  // If it is not, popup is always closed after composition end.
  if (mIgnoreHandleText) {
    mIgnoreHandleText = PR_FALSE;
    if (newValue.Equals(mSearchString))
      return NS_OK;
    NS_ERROR("Now is after composition end event. But the value was changed.");
  }

  // Stop all searches in case they are async.
  StopSearch();

  if (!mInput) {
    // StopSearch() can call PostSearchCleanup() which might result
    // in a blur event, which could null out mInput, so we need to check it
    // again.  See bug #395344 for more details
    return NS_OK;
  }

  PRBool disabled;
  input->GetDisableAutoComplete(&disabled);
  NS_ENSURE_TRUE(!disabled, NS_OK);

  // Don't search again if the new string is the same as the last search
  if (newValue.Length() > 0 && newValue.Equals(mSearchString))
    return NS_OK;

  // Determine if the user has removed text from the end (probably by backspacing)
  if (newValue.Length() < mSearchString.Length() &&
      Substring(mSearchString, 0, newValue.Length()).Equals(newValue))
  {
    // We need to throw away previous results so we don't try to search through them again
    ClearResults();
    mBackspaced = PR_TRUE;
  } else
    mBackspaced = PR_FALSE;

  mSearchString = newValue;

  // Don't search if the value is empty
  if (newValue.Length() == 0) {
    ClosePopup();
    return NS_OK;
  }

  StartSearchTimer();

  return NS_OK;
}
// typedef PRBool
// (*PR_CALLBACK nsHashtableEnumFunc)
//      (nsHashKey *aKey, void *aData, void* aClosure);
PRBool PR_CALLBACK
CheckLDAPOperationResult(nsHashKey *aKey, void *aData, void* aClosure)
{
    int lderrno;
    nsresult rv;
    PRInt32 returnCode;
    LDAPMessage *msgHandle;
    nsCOMPtr<nsILDAPMessage> msg;
    PRBool operationFinished = PR_TRUE;
    struct timeval timeout = { 0, 0 }; 
    PRIntervalTime sleepTime = PR_MillisecondsToInterval(40);

    // we need to access some of the connection loop's objects
    //
    nsLDAPConnectionLoop *loop = 
        static_cast<nsLDAPConnectionLoop *>(aClosure);

    // get the console service so we can log messages
    //
    nsCOMPtr<nsIConsoleService> consoleSvc = 
        do_GetService(kConsoleServiceContractId, &rv);
    if (NS_FAILED(rv)) {
        NS_ERROR("CheckLDAPOperationResult() couldn't get console service");
        return NS_ERROR_FAILURE;
    }

    returnCode = ldap_result(loop->mRawConn->mConnectionHandle,
                             aKey->HashCode(), LDAP_MSG_ONE,
                                 &timeout, &msgHandle);

        // if we didn't error or timeout, create an nsILDAPMessage
        //      
        switch (returnCode) {

        case 0: // timeout

            // the connection may not exist yet.  sleep for a while
            // to avoid a problem where the LDAP connection/thread isn't 
            // ready quite yet, and we want to avoid a very busy loop.
            //
            PR_Sleep(sleepTime);
            return PR_TRUE;

        case -1: // something went wrong 

        lderrno = ldap_get_lderrno(loop->mRawConn->mConnectionHandle, 0, 0);

            // Sleep briefly, to avoid a very busy loop again.
            //
            PR_Sleep(sleepTime);

            switch (lderrno) {

            case LDAP_SERVER_DOWN:
                // We might want to shutdown the thread here, but it has
                // implications to the user of the nsLDAPConnection, so
                // for now we just ignore it. It's up to the owner of
                // the nsLDAPConnection to detect the error, and then
                // create a new connection.
                //
                PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, 
                       ("CheckLDAPOperationResult(): ldap_result returned" 
                        " LDAP_SERVER_DOWN"));
                break;

            case LDAP_DECODING_ERROR:
                consoleSvc->LogStringMessage(
                    NS_LITERAL_STRING("LDAP: WARNING: decoding error; possible corrupt data received").get());
                NS_WARNING("CheckLDAPOperationResult(): ldaperrno = "
                           "LDAP_DECODING_ERROR after ldap_result()");
                break;

            case LDAP_NO_MEMORY:
                NS_ERROR("CheckLDAPOperationResult(): Couldn't allocate memory"
                         " while getting async operation result");
                // punt and hope things work out better next time around
                break;

            case LDAP_PARAM_ERROR:
                // I think it's possible to hit a race condition where we're
                // continuing to poll for a result after the C SDK connection
                // has removed the operation because the connection has gone
                // dead.  In theory we should fix this.  Practically, it's
                // unclear to me whether it matters.
                //
                NS_WARNING("CheckLDAPOperationResult(): ldap_result returned"
                           " LDAP_PARAM_ERROR");
                break;

            default:
                NS_ERROR("CheckLDAPOperationResult(): lderrno set to "
                           "unexpected value after ldap_result() "
                           "call in nsLDAPConnection::Run()");
                PR_LOG(gLDAPLogModule, PR_LOG_ERROR, 
                       ("lderrno = 0x%x", lderrno));
                break;
            }
            break;

        case LDAP_RES_SEARCH_ENTRY:
        case LDAP_RES_SEARCH_REFERENCE:
            // XXX what should we do with LDAP_RES_SEARCH_EXTENDED?

            // not done yet, so we shouldn't remove the op from the conn q
            operationFinished = PR_FALSE;

            // fall through to default case

        default: // initialize the message and call the callback

            // we want nsLDAPMessage specifically, not a compatible, since
            // we're sharing native objects used by the LDAP C SDK
            //
            nsLDAPMessage *rawMsg;
            NS_NEWXPCOM(rawMsg, nsLDAPMessage);
            if (!rawMsg) {
            NS_ERROR("CheckLDAPOperationResult(): couldn't allocate memory"
                     " for new LDAP message; search entry dropped");
                // punt and hope things work out better next time around
                break;
            }

            // initialize the message, using a protected method not available
            // through nsILDAPMessage (which is why we need the raw pointer)
            //
            rv = rawMsg->Init(loop->mRawConn, msgHandle);

            switch (rv) {

            case NS_OK: {
                PRInt32 errorCode;
                rawMsg->GetErrorCode(&errorCode);
                // maybe a version error, e.g., using v3 on a v2 server.
                // if we're using v3, try v2.
                //
                if (errorCode == LDAP_PROTOCOL_ERROR && 
                   loop->mRawConn->mVersion == nsILDAPConnection::VERSION3) {
                    nsCAutoString password;
                    loop->mRawConn->mVersion = nsILDAPConnection::VERSION2;
                    ldap_set_option(loop->mRawConn->mConnectionHandle,
                          LDAP_OPT_PROTOCOL_VERSION, &loop->mRawConn->mVersion);
                    nsCOMPtr <nsILDAPOperation> operation = 
                      static_cast<nsILDAPOperation *>(static_cast<nsISupports *>(aData));
                    // we pass in an empty password to tell the operation that 
                    // it should use the cached password.
                    //
                    rv = operation->SimpleBind(password);
                    if (NS_SUCCEEDED(rv)) {
                        operationFinished = PR_FALSE;
                        // we don't want to notify callers that we're done...
                        return PR_TRUE;
                    }
                }
            }
            break;

            case NS_ERROR_LDAP_DECODING_ERROR:
                consoleSvc->LogStringMessage(
                    NS_LITERAL_STRING("LDAP: WARNING: decoding error; possible corrupt data received").get());
            NS_WARNING("CheckLDAPOperationResult(): ldaperrno = "
                           "LDAP_DECODING_ERROR after ldap_result()");
            return PR_TRUE;

            case NS_ERROR_OUT_OF_MEMORY:
                // punt and hope things work out better next time around
            return PR_TRUE;

            case NS_ERROR_ILLEGAL_VALUE:
            case NS_ERROR_UNEXPECTED:
            default:
                // shouldn't happen; internal error
                //
            NS_ERROR("CheckLDAPOperationResult(): nsLDAPMessage::Init() "
                           "returned unexpected value.");

                // punt and hope things work out better next time around
            return PR_TRUE;
            }

            // now let the scoping mechanisms provided by nsCOMPtr manage
            // the reference for us.
            //
            msg = rawMsg;

            // invoke the callback on the nsILDAPOperation corresponding to 
            // this message
            //
        rv = loop->mRawConn->InvokeMessageCallback(msgHandle, msg, 
                                                    operationFinished);
            if (NS_FAILED(rv)) {
            NS_ERROR("CheckLDAPOperationResult(): error invoking message"
                     " callback");
                // punt and hope things work out better next time around
            return PR_TRUE;
            }

            break;
        }       

    return PR_TRUE;
}
NS_IMETHODIMP
nsAutoCompleteController::HandleKeyNavigation(PRUint32 aKey, PRBool *_retval)
{
  // By default, don't cancel the event
  *_retval = PR_FALSE;

  if (!mInput) {
    // Stop all searches in case they are async.
    StopSearch();
    // Note: if now is after blur and IME end composition,
    // check mInput before calling.
    // See https://bugzilla.mozilla.org/show_bug.cgi?id=193544#c31
    NS_ERROR("Called before attaching to the control or after detaching from the control");
    return NS_OK;
  }

  nsCOMPtr<nsIAutoCompleteInput> input(mInput);
  nsCOMPtr<nsIAutoCompletePopup> popup;
  input->GetPopup(getter_AddRefs(popup));
  NS_ENSURE_TRUE(popup != nsnull, NS_ERROR_FAILURE);

  PRBool disabled;
  input->GetDisableAutoComplete(&disabled);
  NS_ENSURE_TRUE(!disabled, NS_OK);

  if (aKey == nsIDOMKeyEvent::DOM_VK_UP ||
      aKey == nsIDOMKeyEvent::DOM_VK_DOWN ||
      aKey == nsIDOMKeyEvent::DOM_VK_PAGE_UP ||
      aKey == nsIDOMKeyEvent::DOM_VK_PAGE_DOWN)
  {
    // Prevent the input from handling up/down events, as it may move
    // the cursor to home/end on some systems
    *_retval = PR_TRUE;

    PRBool isOpen = PR_FALSE;
    input->GetPopupOpen(&isOpen);
    if (isOpen) {
      PRBool reverse = aKey == nsIDOMKeyEvent::DOM_VK_UP ||
                      aKey == nsIDOMKeyEvent::DOM_VK_PAGE_UP ? PR_TRUE : PR_FALSE;
      PRBool page = aKey == nsIDOMKeyEvent::DOM_VK_PAGE_UP ||
                    aKey == nsIDOMKeyEvent::DOM_VK_PAGE_DOWN ? PR_TRUE : PR_FALSE;

      // Fill in the value of the textbox with whatever is selected in the popup
      // if the completeSelectedIndex attribute is set.  We check this before
      // calling SelectBy of an earlier attempt to avoid crashing.
      PRBool completeSelection;
      input->GetCompleteSelectedIndex(&completeSelection);

      // Instruct the result view to scroll by the given amount and direction
      popup->SelectBy(reverse, page);

      if (completeSelection)
      {
        PRInt32 selectedIndex;
        popup->GetSelectedIndex(&selectedIndex);
        if (selectedIndex >= 0) {
          //  A result is selected, so fill in its value
          nsAutoString value;
          if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, PR_TRUE, value))) {
            input->SetTextValue(value);
            input->SelectTextRange(value.Length(), value.Length());
          }
        } else {
          // Nothing is selected, so fill in the last typed value
          input->SetTextValue(mSearchString);
          input->SelectTextRange(mSearchString.Length(), mSearchString.Length());
        }
      }
    } else {
#ifdef XP_MACOSX
      // on Mac, only show the popup if the caret is at the start or end of
      // the input and there is no selection, so that the default defined key
      // shortcuts for up and down move to the beginning and end of the field
      // otherwise.
      PRInt32 start, end;
      if (aKey == nsIDOMKeyEvent::DOM_VK_UP) {
        input->GetSelectionStart(&start);
        input->GetSelectionEnd(&end);
        if (start > 0 || start != end)
          *_retval = PR_FALSE;
      }
      else if (aKey == nsIDOMKeyEvent::DOM_VK_DOWN) {
        nsAutoString text;
        input->GetTextValue(text);
        input->GetSelectionStart(&start);
        input->GetSelectionEnd(&end);
        if (start != end || end < (PRInt32)text.Length())
          *_retval = PR_FALSE;
      }
#endif
      if (*_retval) {
        // Open the popup if there has been a previous search, or else kick off a new search
        if (mResults.Count() > 0) {
          if (mRowCount) {
            OpenPopup();
          }
        } else {
          // Stop all searches in case they are async.
          StopSearch();

          if (!mInput) {
            // StopSearch() can call PostSearchCleanup() which might result
            // in a blur event, which could null out mInput, so we need to check it
            // again.  See bug #395344 for more details
            return NS_OK;
          }

          StartSearchTimer();
        }
      }
    }
  } else if (   aKey == nsIDOMKeyEvent::DOM_VK_LEFT
             || aKey == nsIDOMKeyEvent::DOM_VK_RIGHT
#ifndef XP_MACOSX
             || aKey == nsIDOMKeyEvent::DOM_VK_HOME
#endif
            )
  {
    // The user hit a text-navigation key.
    PRBool isOpen = PR_FALSE;
    input->GetPopupOpen(&isOpen);
    if (isOpen) {
      PRInt32 selectedIndex;
      popup->GetSelectedIndex(&selectedIndex);
      PRBool shouldComplete;
      input->GetCompleteDefaultIndex(&shouldComplete);
      if (selectedIndex >= 0) {
        // The pop-up is open and has a selection, take its value
        nsAutoString value;
        if (NS_SUCCEEDED(GetResultValueAt(selectedIndex, PR_TRUE, value))) {
          input->SetTextValue(value);
          input->SelectTextRange(value.Length(), value.Length());
        }
      }
      else if (shouldComplete) {
        // We usually try to preserve the casing of what user has typed, but
        // if he wants to autocomplete, we will replace the value with the
        // actual autocomplete result.
        // The user wants explicitely to use that result, so this ensures
        // association of the result with the autocompleted text.
        nsAutoString value;
        nsAutoString inputValue;
        input->GetTextValue(inputValue);
        if (NS_SUCCEEDED(GetDefaultCompleteValue(selectedIndex, PR_FALSE, value)) &&
            value.Equals(inputValue, nsCaseInsensitiveStringComparator())) {
          input->SetTextValue(value);
          input->SelectTextRange(value.Length(), value.Length());
        }
      }
      // Close the pop-up even if nothing was selected
      ClearSearchTimer();
      ClosePopup();
    }
    // Update last-searched string to the current input, since the input may
    // have changed.  Without this, subsequent backspaces look like text
    // additions, not text deletions.
    nsAutoString value;
    input->GetTextValue(value);
    mSearchString = value;
  }

  return NS_OK;
}
NS_IMETHODIMP
nsLDAPConnection::OnLookupComplete(nsICancelable *aRequest,
                                   nsIDNSRecord  *aRecord,
                                   nsresult       aStatus)
{    
    nsresult rv = NS_OK;

    if (aRecord) {
        // Build mResolvedIP list
        //
        mResolvedIP.Truncate();

        PRInt32 index = 0;
        char addrbuf[64];
        PRNetAddr addr;

        while (NS_SUCCEEDED(aRecord->GetNextAddr(0, &addr))) {
            // We can only use v4 addresses
            //
            PRBool v4mapped = PR_FALSE;
            if (addr.raw.family == PR_AF_INET6)
                v4mapped = PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped);
            if (addr.raw.family == PR_AF_INET || v4mapped) {
                // If there are more IPs in the list, we separate them with
                // a space, as supported/used by the LDAP C-SDK.
                //
                if (index++)
                    mResolvedIP.Append(' ');

                // Convert the IPv4 address to a string, and append it to our
                // list of IPs.  Strip leading '::FFFF:' (the IPv4-mapped-IPv6 
                // indicator) if present.
                //
                PR_NetAddrToString(&addr, addrbuf, sizeof(addrbuf));
                if ((addrbuf[0] == ':') && (strlen(addrbuf) > 7))
                    mResolvedIP.Append(addrbuf+7);
                else
                    mResolvedIP.Append(addrbuf);
            }
        }
    }

    if (NS_FAILED(aStatus)) {
        // The DNS service failed, lets pass something reasonable
        // back to the listener.
        //
        switch (aStatus) {
        case NS_ERROR_OUT_OF_MEMORY:
        case NS_ERROR_UNKNOWN_HOST:
        case NS_ERROR_FAILURE:
        case NS_ERROR_OFFLINE:
            rv = aStatus;
            break;

        default:
            rv = NS_ERROR_UNEXPECTED;
            break;
        }
    } else if (!mResolvedIP.Length()) {
        // We have no host resolved, that is very bad, and should most
        // likely have been caught earlier.
        //
        NS_ERROR("nsLDAPConnection::OnStopLookup(): the resolved IP "
                 "string is empty.\n");
        
        rv = NS_ERROR_UNKNOWN_HOST;
    } else {
        // We've got the IP(s) for the hostname, now lets setup the
        // LDAP connection using this information. Note that if the
        // LDAP server returns a referral, the C-SDK will perform a
        // new, synchronous DNS lookup, which might hang (but hopefully
        // if we've come this far, DNS is working properly).
        //
        mConnectionHandle = ldap_init(mResolvedIP.get(),
                                      mPort == -1 ? LDAP_PORT : mPort);
        // Check that we got a proper connection, and if so, setup the
        // threading functions for this connection.
        //
        if ( !mConnectionHandle ) {
            rv = NS_ERROR_FAILURE;  // LDAP C SDK API gives no useful error
        } else {
#if defined(DEBUG_dmose) || defined(DEBUG_bienvenu)
            const int lDebug = 0;
            ldap_set_option(mConnectionHandle, LDAP_OPT_DEBUG_LEVEL, &lDebug);
#endif

            // the C SDK currently defaults to v2.  if we're to use v3, 
            // tell it so.
            //
            int version;
            switch (mVersion) {
            case 2:
                break;
            case 3:
                version = LDAP_VERSION3;
                ldap_set_option(mConnectionHandle, LDAP_OPT_PROTOCOL_VERSION, 
                                &version);
		break;
            default:
                NS_ERROR("nsLDAPConnection::OnLookupComplete(): mVersion"
                         " invalid");
            }

#ifdef MOZ_PSM
            // This code sets up the current connection to use PSM for SSL
            // functionality.  Making this use libssldap instead for
            // non-browser user shouldn't be hard.

            extern nsresult nsLDAPInstallSSL(LDAP *ld, const char *aHostName);

            if (mSSL) {
                if (ldap_set_option(mConnectionHandle, LDAP_OPT_SSL,
                                    LDAP_OPT_ON) != LDAP_SUCCESS ) {
                    NS_ERROR("nsLDAPConnection::OnStopLookup(): Error"
                             " configuring connection to use SSL");
                    rv = NS_ERROR_UNEXPECTED;
                }

                rv = nsLDAPInstallSSL(mConnectionHandle, mDNSHost.get());
                if (NS_FAILED(rv)) {
                    NS_ERROR("nsLDAPConnection::OnStopLookup(): Error"
                             " installing secure LDAP routines for"
                             " connection");
                }
            }
#endif
        }

        // Create a new runnable object, and increment the refcnt. The
        // thread will also hold a strong ref to the runnable, but we need
        // to make sure it doesn't get destructed until we are done with
        // all locking etc. in nsLDAPConnection::Release().
        //
        mRunnable = new nsLDAPConnectionLoop();
        NS_IF_ADDREF(mRunnable);
        if (!mRunnable || NS_FAILED(mRunnable->Init())) {
            rv = NS_ERROR_OUT_OF_MEMORY;
        } else {
            // Here we keep a weak reference in the runnable object to the
            // nsLDAPConnection ("this"). This avoids the problem where a
            // connection can't get destructed because of the new thread
            // keeping a strong reference to it. It also helps us know when
            // we need to exit the new thread: when we can't convert the weak
            // reference to a strong ref, we know that the nsLDAPConnection
            // object is gone, and we need to stop the thread running.
            //
            nsCOMPtr<nsILDAPConnection> conn =
                static_cast<nsILDAPConnection *>(this);

            mRunnable->mWeakConn = do_GetWeakReference(conn);

            // kick off a thread for result listening and marshalling
            //
            rv = NS_NewThread(getter_AddRefs(mThread), mRunnable);
            if (NS_FAILED(rv)) {
                rv = NS_ERROR_NOT_AVAILABLE;
            }
            // XXX(darin): We need to shutdown this thread at some point.
            //             Otherwise, it will stick around until shutdown.
        }
    }

    // Drop the DNS request object, we no longer need it, and set the flag
    // indicating that DNS has finished.
    //
    mDNSRequest = 0;
    mDNSHost.Truncate();

    // Call the listener, and then we can release our reference to it.
    //
    mInitListener->OnLDAPInit(this, rv);
    mInitListener = 0;

    return rv;
}
NS_INTERFACE_MAP_END


// nsIDOMCSSValue


NS_IMETHODIMP
nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText)
{
  nsAutoString tmpStr;
  aCssText.Truncate();
  nsresult result = NS_OK;

  switch (mType) {
    case CSS_PX :
      {
        float val = nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits);
        tmpStr.AppendFloat(val);
        tmpStr.AppendLiteral("px");
        break;
      }
    case CSS_IDENT :
      {
        AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword),
                          tmpStr);
        break;
      }
    case CSS_STRING :
    case CSS_COUNTER : /* FIXME: COUNTER should use an object */
      {
        tmpStr.Append(mValue.mString);
        break;
      }
    case CSS_URI :
      {
        if (mValue.mURI) {
          nsCAutoString specUTF8;
          mValue.mURI->GetSpec(specUTF8);

          tmpStr.AssignLiteral("url(");
          nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(specUTF8),
                                              tmpStr);
          tmpStr.AppendLiteral(")");
        } else {
          // XXXldb Any better ideas?  It's good to have something that
          // doesn't parse so that things round-trip "correctly".
          tmpStr.Assign(NS_LITERAL_STRING("url(invalid-url:)"));
        }
        break;
      }
    case CSS_ATTR :
      {
        tmpStr.AppendLiteral("attr(");
        tmpStr.Append(mValue.mString);
        tmpStr.Append(PRUnichar(')'));
        break;
      }
    case CSS_PERCENTAGE :
      {
        tmpStr.AppendFloat(mValue.mFloat * 100);
        tmpStr.Append(PRUnichar('%'));
        break;
      }
    case CSS_NUMBER :
      {
        tmpStr.AppendFloat(mValue.mFloat);
        break;
      }
    case CSS_RECT :
      {
        NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null");
        NS_NAMED_LITERAL_STRING(comma, ", ");
        nsCOMPtr<nsIDOMCSSPrimitiveValue> sideCSSValue;
        nsAutoString sideValue;
        tmpStr.AssignLiteral("rect(");
        // get the top
        result = mValue.mRect->GetTop(getter_AddRefs(sideCSSValue));
        if (NS_FAILED(result))
          break;
        result = sideCSSValue->GetCssText(sideValue);
        if (NS_FAILED(result))
          break;
        tmpStr.Append(sideValue + comma);
        // get the right
        result = mValue.mRect->GetRight(getter_AddRefs(sideCSSValue));
        if (NS_FAILED(result))
          break;
        result = sideCSSValue->GetCssText(sideValue);
        if (NS_FAILED(result))
          break;
        tmpStr.Append(sideValue + comma);
        // get the bottom
        result = mValue.mRect->GetBottom(getter_AddRefs(sideCSSValue));
        if (NS_FAILED(result))
          break;
        result = sideCSSValue->GetCssText(sideValue);
        if (NS_FAILED(result))
          break;
        tmpStr.Append(sideValue + comma);
        // get the left
        result = mValue.mRect->GetLeft(getter_AddRefs(sideCSSValue));
        if (NS_FAILED(result))
          break;
        result = sideCSSValue->GetCssText(sideValue);
        if (NS_FAILED(result))
          break;
        tmpStr.Append(sideValue + NS_LITERAL_STRING(")"));
        break;
      }
    case CSS_RGBCOLOR :
      {
        NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null");
        NS_NAMED_LITERAL_STRING(comma, ", ");
        nsCOMPtr<nsIDOMCSSPrimitiveValue> colorCSSValue;
        nsAutoString colorValue;
        if (mValue.mColor->HasAlpha())
          tmpStr.AssignLiteral("rgba(");
        else
          tmpStr.AssignLiteral("rgb(");

        // get the red component
        result = mValue.mColor->GetRed(getter_AddRefs(colorCSSValue));
        if (NS_FAILED(result))
          break;
        result = colorCSSValue->GetCssText(colorValue);
        if (NS_FAILED(result))
          break;
        tmpStr.Append(colorValue + comma);

        // get the green component
        result = mValue.mColor->GetGreen(getter_AddRefs(colorCSSValue));
        if (NS_FAILED(result))
          break;
        result = colorCSSValue->GetCssText(colorValue);
        if (NS_FAILED(result))
          break;
        tmpStr.Append(colorValue + comma);

        // get the blue component
        result = mValue.mColor->GetBlue(getter_AddRefs(colorCSSValue));
        if (NS_FAILED(result))
          break;
        result = colorCSSValue->GetCssText(colorValue);
        if (NS_FAILED(result))
          break;
        tmpStr.Append(colorValue);

        if (mValue.mColor->HasAlpha()) {
          // get the alpha component
          result = mValue.mColor->GetAlpha(getter_AddRefs(colorCSSValue));
          if (NS_FAILED(result))
            break;
          result = colorCSSValue->GetCssText(colorValue);
          if (NS_FAILED(result))
            break;
          tmpStr.Append(comma + colorValue);
        }

        tmpStr.Append(NS_LITERAL_STRING(")"));

        break;
      }
    case CSS_S :
      {
        tmpStr.AppendFloat(mValue.mFloat);
        tmpStr.AppendLiteral("s");
        break;
      }
    case CSS_CM :
    case CSS_MM :
    case CSS_IN :
    case CSS_PT :
    case CSS_PC :
    case CSS_UNKNOWN :
    case CSS_EMS :
    case CSS_EXS :
    case CSS_DEG :
    case CSS_RAD :
    case CSS_GRAD :
    case CSS_MS :
    case CSS_HZ :
    case CSS_KHZ :
    case CSS_DIMENSION :
      NS_ERROR("We have a bogus value set.  This should not happen");
      return NS_ERROR_DOM_INVALID_ACCESS_ERR;
  }

  if (NS_SUCCEEDED(result)) {
    aCssText.Assign(tmpStr);
  }

  return NS_OK;
}
Example #25
0
bool
GLLibraryEGL::EnsureInitialized()
{
    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef MOZ_B2G
    if (!sCurrentContext.init())
      MOZ_CRASH("Tls init failed");
#endif

#ifdef XP_WIN
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

        // Also note that we intentionally leak the libs we load.

        do {
            // Windows 8.1 has d3dcompiler_47.dll in the system directory.
            // Try it first. Note that _46 will never be in the system
            // directory and we ship with at least _43. So there is no point
            // trying _46 and _43 in the system directory.

            if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
                break;

#ifdef MOZ_D3DCOMPILER_VISTA_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
                break;
#endif

#ifdef MOZ_D3DCOMPILER_XP_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
                break;
#endif

            MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
        } while (false);

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }

#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(Terminate),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
        // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
        // can only be queried by using a special eglQueryString.
        { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
          { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
        { nullptr, { nullptr } }
    };

    // Do not warn about the failure to load this - see bug 1092191
    GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr,
                                 false);

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
    MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                       "Couldn't find eglQueryStringImplementationANDROID");
#endif

    mEGLDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);

    const char* vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
    if (vendor && (strstr(vendor, "TransGaming") != 0 ||
                   strstr(vendor, "Google Inc.") != 0))
    {
        mIsANGLE = true;
    }

    if (mIsANGLE) {
        EGLDisplay newDisplay = EGL_NO_DISPLAY;

        // D3D11 ANGLE only works with OMTC; there's a bug in the non-OMTC layer
        // manager, and it's pointless to try to fix it.  We also don't try
        // D3D11 ANGLE if the layer manager is prefering D3D9 (hrm, do we care?)
        if (gfxPrefs::LayersOffMainThreadCompositionEnabled() &&
            !gfxPrefs::LayersPreferD3D9())
        {
            if (gfxPrefs::WebGLANGLEForceD3D11()) {
                newDisplay = GetAndInitDisplay(*this,
                                               LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
            } else if (gfxPrefs::WebGLANGLETryD3D11() && gfxPlatform::CanUseDirect3D11ANGLE()) {
                newDisplay = GetAndInitDisplay(*this,
                                               LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
            }
        }

        if (newDisplay != EGL_NO_DISPLAY) {
            DebugOnly<EGLBoolean> success = fTerminate(mEGLDisplay);
            MOZ_ASSERT(success == LOCAL_EGL_TRUE);

            mEGLDisplay = newDisplay;

            vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
        }
    }

    InitExtensions();

    GLLibraryLoader::PlatformLookupFunction lookupFunction =
            (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    //XXX: use correct extension name
    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*)&mSymbols.fSurfaceReleaseSyncANGLE, { "eglSurfaceReleaseSyncANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fSurfaceReleaseSyncANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    if (IsExtensionSupported(ANDROID_native_fence_sync)) {
        GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &nativeFenceSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(ANDROID_native_fence_sync);

            mSymbols.fDupNativeFenceFDANDROID = nullptr;
        }
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}
Example #26
0
NS_IMETHODIMP
nsSHEntry::AddChild(nsISHEntry* aChild, int32_t aOffset)
{
  if (aChild) {
    NS_ENSURE_SUCCESS(aChild->SetParent(this), NS_ERROR_FAILURE);
  }

  if (aOffset < 0) {
    mChildren.AppendObject(aChild);
    return NS_OK;
  }

  //
  // Bug 52670: Ensure children are added in order.
  //
  //  Later frames in the child list may load faster and get appended
  //  before earlier frames, causing session history to be scrambled.
  //  By growing the list here, they are added to the right position.
  //
  //  Assert that aOffset will not be so high as to grow us a lot.
  //
  NS_ASSERTION(aOffset < (mChildren.Count() + 1023), "Large frames array!\n");

  bool newChildIsDyn = false;
  if (aChild) {
    aChild->IsDynamicallyAdded(&newChildIsDyn);
  }

  // If the new child is dynamically added, try to add it to aOffset, but if
  // there are non-dynamically added children, the child must be after those.
  if (newChildIsDyn) {
    int32_t lastNonDyn = aOffset - 1;
    for (int32_t i = aOffset; i < mChildren.Count(); ++i) {
      nsISHEntry* entry = mChildren[i];
      if (entry) {
        bool dyn = false;
        entry->IsDynamicallyAdded(&dyn);
        if (dyn) {
          break;
        } else {
          lastNonDyn = i;
        }
      }
    }
    // InsertObjectAt allows only appending one object.
    // If aOffset is larger than Count(), we must first manually
    // set the capacity.
    if (aOffset > mChildren.Count()) {
      mChildren.SetCount(aOffset);
    }
    if (!mChildren.InsertObjectAt(aChild, lastNonDyn + 1)) {
      NS_WARNING("Adding a child failed!");
      aChild->SetParent(nullptr);
      return NS_ERROR_FAILURE;
    }
  } else {
    // If the new child isn't dynamically added, it should be set to aOffset.
    // If there are dynamically added children before that, those must be
    // moved to be after aOffset.
    if (mChildren.Count() > 0) {
      int32_t start = std::min(mChildren.Count() - 1, aOffset);
      int32_t dynEntryIndex = -1;
      nsISHEntry* dynEntry = nullptr;
      for (int32_t i = start; i >= 0; --i) {
        nsISHEntry* entry = mChildren[i];
        if (entry) {
          bool dyn = false;
          entry->IsDynamicallyAdded(&dyn);
          if (dyn) {
            dynEntryIndex = i;
            dynEntry = entry;
          } else {
            break;
          }
        }
      }

      if (dynEntry) {
        nsCOMArray<nsISHEntry> tmp;
        tmp.SetCount(aOffset - dynEntryIndex + 1);
        mChildren.InsertObjectsAt(tmp, dynEntryIndex);
        NS_ASSERTION(mChildren[aOffset + 1] == dynEntry, "Whaat?");
      }
    }

    // Make sure there isn't anything at aOffset.
    if (aOffset < mChildren.Count()) {
      nsISHEntry* oldChild = mChildren[aOffset];
      if (oldChild && oldChild != aChild) {
        NS_ERROR("Adding a child where we already have a child? This may misbehave");
        oldChild->SetParent(nullptr);
      }
    }

    mChildren.ReplaceObjectAt(aChild, aOffset);
  }

  return NS_OK;
}
nsresult
nsXFormsMDGEngine::Recalculate(nsCOMArray<nsIDOMNode> *aChangedNodes)
{
  NS_ENSURE_ARG(aChangedNodes);

#ifdef DEBUG_XF_MDG
  printf("nsXFormsMDGEngine::Recalculate(aChangedNodes=|%d|)\n",
         aChangedNodes->Count());
#endif

  // XXX: There's something wrong with the marking of nodes, as we assume that
  // recalculate will always be called first. bug 338146
  nsresult rv = HandleMarkedNodes(aChangedNodes);
  NS_ENSURE_SUCCESS(rv, rv);
  
  PRBool res = PR_TRUE;

  mFirstCalculate = mJustRebuilt;

#ifdef DEBUG_XF_MDG
  printf("\taChangedNodes: %d\n", aChangedNodes->Count());
  printf("\tmNodeToMDG:    %d\n", mNodeToMDG.Count());
  printf("\tmNodeStates:   %d\n", mNodeStates.Count());
  printf("\tGraph nodes:   %d\n", mGraph.Count());
#endif
  
  // Go through all dirty nodes in the graph
  nsXFormsMDGNode* g;
  for (PRInt32 i = 0; i < mGraph.Count(); ++i) {
    g = static_cast<nsXFormsMDGNode*>(mGraph[i]);

    if (!g) {
      NS_WARNING("nsXFormsMDGEngine::Calculate(): Empty node in graph!!!");
      continue;
    }

    NS_ASSERTION(g->mCount == 0,
                 "nsXFormsMDGEngine::Calculate(): Graph node with mCount != 0");

#ifdef DEBUG_XF_MDG
    nsAutoString domNodeName;
    g->mContextNode->GetNodeName(domNodeName);

    printf("\tNode #%d: This=%p, Dirty=%d, DynFunc=%d, Type=%d, Count=%d, Suc=%d, CSize=%d, CPos=%d, Next=%p, HasExpr=%d, domnode=%s\n",
           i, (void*) g, g->IsDirty(), g->mDynFunc, g->mType,
           g->mCount, g->mSuc.Count(), g->mContextSize, g->mContextPosition,
           (void*) g->mNext, g->HasExpr(), NS_ConvertUTF16toUTF8(domNodeName).get());
#endif

    // Ignore node if it is not dirty
    if (!g->IsDirty()) {
      continue;
    }

    nsXFormsNodeState* ns = GetNCNodeState(g->mContextNode);
    NS_ENSURE_TRUE(ns, NS_ERROR_FAILURE);
    
    PRBool constraint = PR_TRUE;
    PRBool conChanged;
    // Find MIP-type and handle it accordingly
    switch (g->mType) {
    case eModel_calculate:
      if (g->HasExpr()) {
        nsCOMPtr<nsISupports> result;
        rv = g->mExpression->EvaluateWithContext(g->mContextNode,
                                                 g->mContextPosition,
                                                 g->mContextSize,
                                                 nsIDOMXPathResult::STRING_TYPE,
                                                 nsnull,
                                                 getter_AddRefs(result));
        NS_ENSURE_SUCCESS(rv, rv);

        nsCOMPtr<nsIDOMXPathResult> xpath_res = do_QueryInterface(result);
        NS_ENSURE_STATE(xpath_res);
        
        nsAutoString nodeval;
        rv = xpath_res->GetStringValue(nodeval);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = SetNodeValueInternal(g->mContextNode,
                                  nodeval,
                                  PR_FALSE,
                                  PR_TRUE);
        if (NS_SUCCEEDED(rv)) {
          NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                         NS_ERROR_FAILURE);
        }

        ns->Set(eFlag_DISPATCH_VALUE_CHANGED, PR_TRUE);
      }

      break;
      
    case eModel_constraint:
      if (g->HasExpr()) {
        rv = BooleanExpression(g, constraint);
        NS_ENSURE_SUCCESS(rv, rv);
      }

      conChanged = ns->IsConstraint() != constraint;
        // On the first calculate after a rebuild (mFirstCalculate) we also
        // add constraints to the set of changed nodes to trigger validation
        // of type information if present.
      if (conChanged || mFirstCalculate) {
        if (conChanged) {
          ns->Set(eFlag_CONSTRAINT, constraint);
          ns->Set(eFlag_DISPATCH_VALID_CHANGED, PR_TRUE);
        }
        NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                       NS_ERROR_FAILURE);
      }

      break;

    case eModel_readonly:
      if (g->HasExpr()) {
        rv = ComputeMIPWithInheritance(eFlag_READONLY,
                                       eFlag_DISPATCH_READONLY_CHANGED,
                                       eFlag_INHERITED_READONLY,
                                       g,
                                       aChangedNodes);
        NS_ENSURE_SUCCESS(rv, rv);
      }
      break;
      
    case eModel_relevant:
      if (g->HasExpr()) {
        rv = ComputeMIPWithInheritance(eFlag_RELEVANT,
                                       eFlag_DISPATCH_RELEVANT_CHANGED,
                                       eFlag_INHERITED_RELEVANT,
                                       g,
                                       aChangedNodes);
        NS_ENSURE_SUCCESS(rv, rv);
      }
      break;
      
    case eModel_required:
      if (g->HasExpr()) {
        PRBool didChange;
        rv = ComputeMIP(eFlag_REQUIRED,
                        eFlag_DISPATCH_REQUIRED_CHANGED,
                        g,
                        didChange);
        NS_ENSURE_SUCCESS(rv, rv);
      
        if (didChange) {
          NS_ENSURE_TRUE(aChangedNodes->AppendObject(g->mContextNode),
                         NS_ERROR_FAILURE);
        }
      }
      break;
      
    default:
      NS_ERROR("There was no expression which matched\n");
      res = PR_FALSE;
      break;
    }

    // Mark successors dirty
    nsXFormsMDGNode* sucnode;
    for (PRInt32 j = 0; j < g->mSuc.Count(); ++j) {
      sucnode = static_cast<nsXFormsMDGNode*>(g->mSuc[j]);
      if (!sucnode) {
        NS_ERROR("nsXFormsMDGEngine::Calculate(): Node has NULL successor!");
        return NS_ERROR_FAILURE;
      }
      sucnode->MarkDirty();
    }

    g->MarkClean();
  }
  nsXFormsUtils::MakeUniqueAndSort(aChangedNodes);
  
#ifdef DEBUG_XF_MDG
  printf("\taChangedNodes: %d\n", aChangedNodes->Count());
  printf("\tmNodeToMDG:    %d\n", mNodeToMDG.Count());
  printf("\tmNodeStates:   %d\n", mNodeStates.Count());
  printf("\tGraph nodes:   %d\n", mGraph.Count());
#endif

  return res;
}
HDC
gfxWindowsNativeDrawing::BeginNativeDrawing()
{
    if (mRenderState == RENDER_STATE_INIT) {
        nsRefPtr<gfxASurface> surf = mContext->CurrentSurface(&mDeviceOffset.x, &mDeviceOffset.y);
        if (!surf || surf->CairoStatus())
            return nsnull;

        gfxMatrix m = mContext->CurrentMatrix();
        if (!m.HasNonTranslation())
            mTransformType = TRANSLATION_ONLY;
        else if (m.HasNonAxisAlignedTransform())
            mTransformType = COMPLEX;
        else
            mTransformType = AXIS_ALIGNED_SCALE;

        // if this is a native win32 surface, we don't have to
        // redirect rendering to our own HDC; in some cases,
        // we may be able to use the HDC from the surface directly.
        if ((surf->GetType() == gfxASurface::SurfaceTypeWin32 ||
             surf->GetType() == gfxASurface::SurfaceTypeWin32Printing) &&
            (surf->GetContentType() == gfxASurface::CONTENT_COLOR ||
             (surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA &&
              (mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA))))
        {
            // grab the DC. This can fail if there is a complex clipping path,
            // in which case we'll have to fall back.
            mWinSurface = static_cast<gfxWindowsSurface*>(static_cast<gfxASurface*>(surf.get()));
            mDC = mWinSurface->GetDCWithClip(mContext);

            if (mDC) {
                if (mTransformType == TRANSLATION_ONLY) {
                    mRenderState = RENDER_STATE_NATIVE_DRAWING;

                    mTranslation = m.GetTranslation();
                } else if (((mTransformType == AXIS_ALIGNED_SCALE)
                            && (mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) ||
                           (mNativeDrawFlags & CAN_COMPLEX_TRANSFORM))
                {
                    mWorldTransform.eM11 = (FLOAT) m.xx;
                    mWorldTransform.eM12 = (FLOAT) m.yx;
                    mWorldTransform.eM21 = (FLOAT) m.xy;
                    mWorldTransform.eM22 = (FLOAT) m.yy;
                    mWorldTransform.eDx  = (FLOAT) m.x0;
                    mWorldTransform.eDy  = (FLOAT) m.y0;

                    mRenderState = RENDER_STATE_NATIVE_DRAWING;
                }
            }
        }

        // If we couldn't do native drawing, then we have to do two-buffer drawing
        // and do alpha recovery
        if (mRenderState == RENDER_STATE_INIT) {
            mRenderState = RENDER_STATE_ALPHA_RECOVERY_BLACK;

            // We round out our native rect here, that way the snapping will
            // happen correctly.
            mNativeRect.RoundOut();

            // we only do the scale bit if we can do an axis aligned
            // scale; otherwise we scale (if necessary) after
            // rendering with cairo.  Note that if we're doing alpha recovery,
            // we cannot do a full complex transform with win32 (I mean, we could, but
            // it would require more code that's not here.)
            if (mTransformType == TRANSLATION_ONLY || !(mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE)) {
                mScale = gfxSize(1.0, 1.0);

                // Add 1 to the surface size; it's guaranteed to not be incorrect,
                // and it fixes bug 382458
                // There's probably a better fix, but I haven't figured out
                // the root cause of the problem.
                mTempSurfaceSize =
                    gfxIntSize((PRInt32) NS_ceil(mNativeRect.Width() + 1),
                               (PRInt32) NS_ceil(mNativeRect.Height() + 1));
            } else {
                // figure out the scale factors
                mScale = m.ScaleFactors(PR_TRUE);

                mWorldTransform.eM11 = (FLOAT) mScale.width;
                mWorldTransform.eM12 = 0.0f;
                mWorldTransform.eM21 = 0.0f;
                mWorldTransform.eM22 = (FLOAT) mScale.height;
                mWorldTransform.eDx  = 0.0f;
                mWorldTransform.eDy  = 0.0f;

                // See comment above about "+1"
                mTempSurfaceSize =
                    gfxIntSize((PRInt32) NS_ceil(mNativeRect.Width() * mScale.width + 1),
                               (PRInt32) NS_ceil(mNativeRect.Height() * mScale.height + 1));
            }
        }
    }

    if (mRenderState == RENDER_STATE_NATIVE_DRAWING) {
        // we can just do native drawing directly to the context's surface

        // do we need to use SetWorldTransform?
        if (mTransformType != TRANSLATION_ONLY) {
            SetGraphicsMode(mDC, GM_ADVANCED);
            GetWorldTransform(mDC, &mOldWorldTransform);
            SetWorldTransform(mDC, &mWorldTransform);
        }
        GetViewportOrgEx(mDC, &mOrigViewportOrigin);
        SetViewportOrgEx(mDC,
                         mOrigViewportOrigin.x + (int)mDeviceOffset.x,
                         mOrigViewportOrigin.y + (int)mDeviceOffset.y,
                         NULL);

        return mDC;
    } else if (mRenderState == RENDER_STATE_ALPHA_RECOVERY_BLACK ||
               mRenderState == RENDER_STATE_ALPHA_RECOVERY_WHITE)
    {
        // we're going to use mWinSurface to create our temporary surface here

        // get us a RGB24 DIB; DIB is important, because
        // we can later call GetImageSurface on it.
        mWinSurface = new gfxWindowsSurface(mTempSurfaceSize);
        mDC = mWinSurface->GetDC();

        RECT r = { 0, 0, mTempSurfaceSize.width, mTempSurfaceSize.height };
        if (mRenderState == RENDER_STATE_ALPHA_RECOVERY_BLACK)
            FillRect(mDC, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));
        else
            FillRect(mDC, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));

        if ((mTransformType != TRANSLATION_ONLY) &&
            (mNativeDrawFlags & CAN_AXIS_ALIGNED_SCALE))
        {
            SetGraphicsMode(mDC, GM_ADVANCED);
            SetWorldTransform(mDC, &mWorldTransform);
        }

        return mDC;
    } else {
        NS_ERROR("Bogus render state!");
        return nsnull;
    }
}
NS_IMETHODIMP
nsUrlClassifierStreamUpdater::DownloadUpdates(
                                const nsACString &aRequestTables,
                                const nsACString &aRequestBody,
                                const nsACString &aClientKey,
                                nsIUrlClassifierCallback *aSuccessCallback,
                                nsIUrlClassifierCallback *aUpdateErrorCallback,
                                nsIUrlClassifierCallback *aDownloadErrorCallback,
                                bool *_retval)
{
  NS_ENSURE_ARG(aSuccessCallback);
  NS_ENSURE_ARG(aUpdateErrorCallback);
  NS_ENSURE_ARG(aDownloadErrorCallback);

  if (mIsUpdating) {
    LOG(("already updating, skipping update"));
    *_retval = false;
    return NS_OK;
  }

  if (!mUpdateUrl) {
    NS_ERROR("updateUrl not set");
    return NS_ERROR_NOT_INITIALIZED;
  }

  nsresult rv;

  if (!mInitialized) {
    // Add an observer for shutdown so we can cancel any pending list
    // downloads.  quit-application is the same event that the download
    // manager listens for and uses to cancel pending downloads.
    nsCOMPtr<nsIObserverService> observerService =
      mozilla::services::GetObserverService();
    if (!observerService)
      return NS_ERROR_FAILURE;

    observerService->AddObserver(this, gQuitApplicationMessage, false);

    mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    mInitialized = true;
  }

  rv = mDBService->BeginUpdate(this, aRequestTables, aClientKey);
  if (rv == NS_ERROR_NOT_AVAILABLE) {
    LOG(("already updating, skipping update"));
    *_retval = false;
    return NS_OK;
  } else if (NS_FAILED(rv)) {
    return rv;
  }

  mSuccessCallback = aSuccessCallback;
  mUpdateErrorCallback = aUpdateErrorCallback;
  mDownloadErrorCallback = aDownloadErrorCallback;

  mIsUpdating = true;
  *_retval = true;

  nsAutoCString urlSpec;
  mUpdateUrl->GetAsciiSpec(urlSpec);

  LOG(("FetchUpdate: %s", urlSpec.get()));
  //LOG(("requestBody: %s", aRequestBody.get()));

  return FetchUpdate(mUpdateUrl, aRequestBody, EmptyCString(), EmptyCString());
}
Example #30
0
nsresult
nsIndexedToHTML::DoOnStartRequest(nsIRequest* request, nsISupports *aContext,
                                  nsCString& aBuffer) {
    nsresult rv;

    nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
    nsCOMPtr<nsIURI> uri;
    rv = channel->GetURI(getter_AddRefs(uri));
    if (NS_FAILED(rv)) return rv;

    channel->SetContentType(NS_LITERAL_CSTRING("text/html"));

    mParser = do_CreateInstance("@mozilla.org/dirIndexParser;1",&rv);
    if (NS_FAILED(rv)) return rv;

    rv = mParser->SetListener(this);
    if (NS_FAILED(rv)) return rv;
    
    rv = mParser->OnStartRequest(request, aContext);
    if (NS_FAILED(rv)) return rv;

    nsAutoCString baseUri, titleUri;
    rv = uri->GetAsciiSpec(baseUri);
    if (NS_FAILED(rv)) return rv;
    titleUri = baseUri;

    nsCString parentStr;

    nsCString buffer;
    buffer.AppendLiteral("<!DOCTYPE html>\n<html>\n<head>\n");

    // XXX - should be using the 300: line from the parser.
    // We can't guarantee that that comes before any entry, so we'd have to
    // buffer, and do other painful stuff.
    // I'll deal with this when I make the changes to handle welcome messages
    // The .. stuff should also come from the lower level protocols, but that
    // would muck up the XUL display
    // - bbaetz

    bool isScheme = false;
    bool isSchemeFile = false;
    if (NS_SUCCEEDED(uri->SchemeIs("ftp", &isScheme)) && isScheme) {

        // strip out the password here, so it doesn't show in the page title
        // This is done by the 300: line generation in ftp, but we don't use
        // that - see above
        
        nsAutoCString pw;
        rv = uri->GetPassword(pw);
        if (NS_FAILED(rv)) return rv;
        if (!pw.IsEmpty()) {
             nsCOMPtr<nsIURI> newUri;
             rv = uri->Clone(getter_AddRefs(newUri));
             if (NS_FAILED(rv)) return rv;
             rv = newUri->SetPassword(EmptyCString());
             if (NS_FAILED(rv)) return rv;
             rv = newUri->GetAsciiSpec(titleUri);
             if (NS_FAILED(rv)) return rv;
        }

        nsAutoCString path;
        rv = uri->GetPath(path);
        if (NS_FAILED(rv)) return rv;

        if (!path.EqualsLiteral("//") && !path.LowerCaseEqualsLiteral("/%2f")) {
            rv = uri->Resolve(NS_LITERAL_CSTRING(".."),parentStr);
            if (NS_FAILED(rv)) return rv;
        }
    } else if (NS_SUCCEEDED(uri->SchemeIs("file", &isSchemeFile)) && isSchemeFile) {
        nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(uri);
        nsCOMPtr<nsIFile> file;
        rv = fileUrl->GetFile(getter_AddRefs(file));
        if (NS_FAILED(rv)) return rv;
        file->SetFollowLinks(true);
        
        nsAutoCString url;
        rv = net_GetURLSpecFromFile(file, url);
        if (NS_FAILED(rv)) return rv;
        baseUri.Assign(url);
        
        nsCOMPtr<nsIFile> parent;
        rv = file->GetParent(getter_AddRefs(parent));
        
        if (parent && NS_SUCCEEDED(rv)) {
            net_GetURLSpecFromDir(parent, url);
            if (NS_FAILED(rv)) return rv;
            parentStr.Assign(url);
        }

        // Directory index will be always encoded in UTF-8 if this is file url
        buffer.AppendLiteral("<meta charset=\"UTF-8\">\n");

    } else if (NS_SUCCEEDED(uri->SchemeIs("jar", &isScheme)) && isScheme) {
        nsAutoCString path;
        rv = uri->GetPath(path);
        if (NS_FAILED(rv)) return rv;

        // a top-level jar directory URL is of the form jar:foo.zip!/
        // path will be of the form foo.zip!/, and its last two characters
        // will be "!/"
        //XXX this won't work correctly when the name of the directory being
        //XXX displayed ends with "!", but then again, jar: URIs don't deal
        //XXX particularly well with such directories anyway
        if (!StringEndsWith(path, NS_LITERAL_CSTRING("!/"))) {
            rv = uri->Resolve(NS_LITERAL_CSTRING(".."), parentStr);
            if (NS_FAILED(rv)) return rv;
        }
    }
    else {
        // default behavior for other protocols is to assume the channel's
        // URL references a directory ending in '/' -- fixup if necessary.
        nsAutoCString path;
        rv = uri->GetPath(path);
        if (NS_FAILED(rv)) return rv;
        if (baseUri.Last() != '/') {
            baseUri.Append('/');
            path.Append('/');
            uri->SetPath(path);
        }
        if (!path.EqualsLiteral("/")) {
            rv = uri->Resolve(NS_LITERAL_CSTRING(".."), parentStr);
            if (NS_FAILED(rv)) return rv;
        }
    }

    buffer.AppendLiteral("<style type=\"text/css\">\n"
                         ":root {\n"
                         "  font-family: sans-serif;\n"
                         "}\n"
                         "img {\n"
                         "  border: 0;\n"
                         "}\n"
                         "th {\n"
                         "  text-align: start;\n"
                         "  white-space: nowrap;\n"
                         "}\n"
                         "th > a {\n"
                         "  color: inherit;\n"
                         "}\n"
                         "table[order] > thead > tr > th {\n"
                         "  cursor: pointer;\n"
                         "}\n"
                         "table[order] > thead > tr > th::after {\n"
                         "  display: none;\n"
                         "  width: .8em;\n"
                         "  -moz-margin-end: -.8em;\n"
                         "  text-align: end;\n"
                         "}\n"
                         "table[order=\"asc\"] > thead > tr > th::after {\n"
                         "  content: \"\\2193\"; /* DOWNWARDS ARROW (U+2193) */\n"
                         "}\n"
                         "table[order=\"desc\"] > thead > tr > th::after {\n"
                         "  content: \"\\2191\"; /* UPWARDS ARROW (U+2191) */\n"
                         "}\n"
                         "table[order][order-by=\"0\"] > thead > tr > th:first-child > a ,\n"
                         "table[order][order-by=\"1\"] > thead > tr > th:first-child + th > a ,\n"
                         "table[order][order-by=\"2\"] > thead > tr > th:first-child + th + th > a {\n"
                         "  text-decoration: underline;\n"
                         "}\n"
                         "table[order][order-by=\"0\"] > thead > tr > th:first-child::after ,\n"
                         "table[order][order-by=\"1\"] > thead > tr > th:first-child + th::after ,\n"
                         "table[order][order-by=\"2\"] > thead > tr > th:first-child + th + th::after {\n"
                         "  display: inline-block;\n"
                         "}\n"
                         "table.remove-hidden > tbody > tr.hidden-object {\n"
                         "  display: none;\n"
                         "}\n"
                         "td {\n"
                         "  white-space: nowrap;\n"
                         "}\n"
                         "table.ellipsis {\n"
                         "  width: 100%;\n"
                         "  table-layout: fixed;\n"
                         "  border-spacing: 0;\n"
                         "}\n"
                         "table.ellipsis > tbody > tr > td {\n"
                         "  padding: 0;\n"
                         "  overflow: hidden;\n"
                         "  text-overflow: ellipsis;\n"
                         "}\n"
                         "/* name */\n"
                         "/* name */\n"
                         "th:first-child {\n"
                         "  -moz-padding-end: 2em;\n"
                         "}\n"
                         "/* size */\n"
                         "th:first-child + th {\n"
                         "  -moz-padding-end: 1em;\n"
                         "}\n"
                         "td:first-child + td {\n"
                         "  text-align: end;\n"
                         "  -moz-padding-end: 1em;\n"
                         "}\n"
                         "/* date */\n"
                         "td:first-child + td + td {\n"
                         "  -moz-padding-start: 1em;\n"
                         "  -moz-padding-end: .5em;\n"
                         "}\n"
                         "/* time */\n"
                         "td:first-child + td + td + td {\n"
                         "  -moz-padding-start: .5em;\n"
                         "}\n"
                         ".symlink {\n"
                         "  font-style: italic;\n"
                         "}\n"
                         ".dir ,\n"
                         ".symlink ,\n"
                         ".file {\n"
                         "  -moz-margin-start: 20px;\n"
                         "}\n"
                         ".dir::before ,\n"
                         ".file > img {\n"
                         "  -moz-margin-end: 4px;\n"
                         "  -moz-margin-start: -20px;\n"
                         "  max-width: 16px;\n"
                         "  max-height: 16px;\n"
                         "  vertical-align: middle;\n"
                         "}\n"
                         ".dir::before {\n"
                         "  content: url(resource://gre/res/html/folder.png);\n"
                         "}\n"
                         "</style>\n"
                         "<link rel=\"stylesheet\" media=\"screen, projection\" type=\"text/css\""
                         " href=\"chrome://global/skin/dirListing/dirListing.css\">\n"
                         "<script type=\"application/javascript\">\n"
                         "var gTable, gOrderBy, gTBody, gRows, gUI_showHidden;\n"
                         "document.addEventListener(\"DOMContentLoaded\", function() {\n"
                         "  gTable = document.getElementsByTagName(\"table\")[0];\n"
                         "  gTBody = gTable.tBodies[0];\n"
                         "  if (gTBody.rows.length < 2)\n"
                         "    return;\n"
                         "  gUI_showHidden = document.getElementById(\"UI_showHidden\");\n"
                         "  var headCells = gTable.tHead.rows[0].cells,\n"
                         "      hiddenObjects = false;\n"
                         "  function rowAction(i) {\n"
                         "    return function(event) {\n"
                         "      event.preventDefault();\n"
                         "      orderBy(i);\n"
                         "    }\n"
                         "  }\n"
                         "  for (var i = headCells.length - 1; i >= 0; i--) {\n"
                         "    var anchor = document.createElement(\"a\");\n"
                         "    anchor.href = \"\";\n"
                         "    anchor.appendChild(headCells[i].firstChild);\n"
                         "    headCells[i].appendChild(anchor);\n"
                         "    headCells[i].addEventListener(\"click\", rowAction(i), true);\n"
                         "  }\n"
                         "  if (gUI_showHidden) {\n"
                         "    gRows = Array.slice(gTBody.rows);\n"
                         "    hiddenObjects = gRows.some(function (row) row.className == \"hidden-object\");\n"
                         "  }\n"
                         "  gTable.setAttribute(\"order\", \"\");\n"
                         "  if (hiddenObjects) {\n"
                         "    gUI_showHidden.style.display = \"block\";\n"
                         "    updateHidden();\n"
                         "  }\n"
                         "}, \"false\");\n"
                         "function compareRows(rowA, rowB) {\n"
                         "  var a = rowA.cells[gOrderBy].getAttribute(\"sortable-data\") || \"\";\n"
                         "  var b = rowB.cells[gOrderBy].getAttribute(\"sortable-data\") || \"\";\n"
                         "  var intA = +a;\n"
                         "  var intB = +b;\n"
                         "  if (a == intA && b == intB) {\n"
                         "    a = intA;\n"
                         "    b = intB;\n"
                         "  } else {\n"
                         "    a = a.toLowerCase();\n"
                         "    b = b.toLowerCase();\n"
                         "  }\n"
                         "  if (a < b)\n"
                         "    return -1;\n"
                         "  if (a > b)\n"
                         "    return 1;\n"
                         "  return 0;\n"
                         "}\n"
                         "function orderBy(column) {\n"
                         "  if (!gRows)\n"
                         "    gRows = Array.slice(gTBody.rows);\n"
                         "  var order;\n"
                         "  if (gOrderBy == column) {\n"
                         "    order = gTable.getAttribute(\"order\") == \"asc\" ? \"desc\" : \"asc\";\n"
                         "  } else {\n"
                         "    order = \"asc\";\n"
                         "    gOrderBy = column;\n"
                         "    gTable.setAttribute(\"order-by\", column);\n"
                         "    gRows.sort(compareRows);\n"
                         "  }\n"
                         "  gTable.removeChild(gTBody);\n"
                         "  gTable.setAttribute(\"order\", order);\n"
                         "  if (order == \"asc\")\n"
                         "    for (var i = 0; i < gRows.length; i++)\n"
                         "      gTBody.appendChild(gRows[i]);\n"
                         "  else\n"
                         "    for (var i = gRows.length - 1; i >= 0; i--)\n"
                         "      gTBody.appendChild(gRows[i]);\n"
                         "  gTable.appendChild(gTBody);\n"
                         "}\n"
                         "function updateHidden() {\n"
                         "  gTable.className = gUI_showHidden.getElementsByTagName(\"input\")[0].checked ?\n"
                         "                     \"\" :\n"
                         "                     \"remove-hidden\";\n"
                         "}\n"
                         "</script>\n");

    buffer.AppendLiteral("<link rel=\"icon\" type=\"image/png\" href=\"");
    nsCOMPtr<nsIURI> innerUri = NS_GetInnermostURI(uri);
    if (!innerUri)
        return NS_ERROR_UNEXPECTED;
    nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(innerUri));
    //XXX bug 388553: can't use skinnable icons here due to security restrictions
    if (fileURL) {
        //buffer.AppendLiteral("chrome://global/skin/dirListing/local.png");
        buffer.AppendLiteral("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB"
                             "AAAAAQCAYAAAAf8%2F9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i"
                             "ZSBJbWFnZVJlYWR5ccllPAAAAjFJREFUeNqsU8uOElEQPffR"
                             "3XQ3ONASdBJCSBxHos5%2B3Bg3rvkCv8PElS78gPkO%2FATj"
                             "QoUdO2ftrJiRh6aneTb9sOpC4weMN6lcuFV16pxDIfI8x12O"
                             "YIDhcPiu2Wx%2B%2FHF5CW1Z6Jyegt%2FTNEWSJIjjGFEUIQ"
                             "xDrFYrWFSzXC4%2FdLvd95pRKpXKy%2BpRFZ7nwaWo1%2BsG"
                             "nQG2260BKJfLKJVKGI1GEEJw7ateryd0v993W63WEwjgxfn5"
                             "obGYzgCbzcaEbdsIggDj8Riu6z6iUk9SYZMSx8W0LMsM%2FS"
                             "KK75xnJlIq80anQXdbEp0OhcPJ0eiaJnGRMEyyPDsAKKUM9c"
                             "lkYoDo3SZJzzSdp0VSKYmfV1co%2Bz580kw5KDIM8RbRfEnU"
                             "f1HzxtQyMAGcaGruTKczMzEIaqhKifV6jd%2BzGQQB5llunF"
                             "%2FM52BizC2K5sYPYvZcu653tjOM9O93wnYc08gmkgg4VAxi"
                             "xfqFUJT36AYBZGd6PJkFCZnnlBxMp38gqIgLpZB0y4Nph18l"
                             "yWh5FFbrOSxbl3V4G%2BVB7T4ajYYxTyuLtO%2BCvWGgJE1M"
                             "c7JNsJEhvgw%2FQV4fo%2F24nbEsX2u1d5sVyn8sJO0ZAQiI"
                             "YnFh%2BxrfLz%2Fj29cBS%2FO14zg3i8XigW3ZkErDtmKoeM"
                             "%2BAJGRMnXeEPGKf0nCD1ydvkDzU9Jbc6OpR7WIw6L8lQ%2B"
                             "4pQ1%2FlPF0RGM9Ns91Wmptk0GfB4EJkt77vXYj%2F8m%2B8"
                             "y%2FkrwABHbz2H9V68DQAAAABJRU5ErkJggg%3D%3D");
    } else {
        //buffer.AppendLiteral("chrome://global/skin/dirListing/remote.png");
        buffer.AppendLiteral("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB"
                             "AAAAAQCAYAAAAf8%2F9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i"
                             "ZSBJbWFnZVJlYWR5ccllPAAAAeBJREFUeNqcU81O20AQ%2Ft"
                             "Z2AgQSYQRqL1UPVG2hAUQkxLEStz4DrXpLpD5Drz31Cajax%"
                             "2Bghhx6qHIJURBTxIwQRwopCBbZjHMcOTrzermPipsSt1Iw0"
                             "3p3ZmW%2B%2B2R0TxhgOD34wjCHZlQ0iDYz9yvEfhxMTCYhE"
                             "QDIZhkxKd2sqzX2TOD2vBQCQhpPefng1ZP2dVPlLLdpL8SEM"
                             "cxng%2Fbs0RIHhtgs4twxOh%2BHjZxvzDx%2F3GQQiDFISiR"
                             "BLFMPKTRMollzcWECrDVhtxtdRVsL9youPxGj%2FbdfFlUZh"
                             "tDyYbYqWRUdai1oQRZ5oHeHl2gNM%2B01Uqio8RlH%2Bnsaz"
                             "JzNwXcq1B%2BiXPHprlEEymeBfXs1w8XxxihfyuXqoHqpoGj"
                             "ZM04bddgG%2F9%2B8WGj87qDdsrK9m%2BoA%2BpbhQTDh2l1"
                             "%2Bi2weNbSHMZyjvNXmVbqh9Fj5Oz27uEoP%2BSTxANruJs9"
                             "L%2FT6P0ewqPx5nmiAG5f6AoCtN1PbJzuRyJAyDBzzSQYvEr"
                             "f06yYxhGXlEa8H2KVGoasjwLx3Ewk858opQWXm%2B%2Fib9E"
                             "QrBzclLLLy89xYvlpchvtixcX6uo1y%2FzsiwHrkIsgKbp%2"
                             "BYWFOWicuqppoNTnStHzPFCPQhBEBOyGAX4JMADFetubi4BS"
                             "YAAAAABJRU5ErkJggg%3D%3D");
    }
    buffer.AppendLiteral("\">\n<title>");

    // Everything needs to end in a /,
    // otherwise we end up linking to file:///foo/dirfile

    if (!mTextToSubURI) {
        mTextToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
        if (NS_FAILED(rv)) return rv;
    }

    nsXPIDLCString encoding;
    rv = uri->GetOriginCharset(encoding);
    if (NS_FAILED(rv)) return rv;
    if (encoding.IsEmpty()) {
      encoding.AssignLiteral("UTF-8");
    }

    nsXPIDLString unEscapeSpec;
    rv = mTextToSubURI->UnEscapeAndConvert(encoding, titleUri.get(),
                                           getter_Copies(unEscapeSpec));
    // unescape may fail because
    // 1. file URL may be encoded in platform charset for backward compatibility
    // 2. query part may not be encoded in UTF-8 (see bug 261929)
    // so try the platform's default if this is file url
    if (NS_FAILED(rv) && isSchemeFile) {
        nsCOMPtr<nsIPlatformCharset> platformCharset(do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv));
        NS_ENSURE_SUCCESS(rv, rv);
        nsAutoCString charset;
        rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, charset);
        NS_ENSURE_SUCCESS(rv, rv);

        rv = mTextToSubURI->UnEscapeAndConvert(charset.get(), titleUri.get(),
                                               getter_Copies(unEscapeSpec));
    }
    if (NS_FAILED(rv)) return rv;

    nsXPIDLString htmlEscSpec;
    htmlEscSpec.Adopt(nsEscapeHTML2(unEscapeSpec.get(),
                                    unEscapeSpec.Length()));

    nsXPIDLString title;
    const char16_t* formatTitle[] = {
        htmlEscSpec.get()
    };

    rv = mBundle->FormatStringFromName(MOZ_UTF16("DirTitle"),
                                       formatTitle,
                                       sizeof(formatTitle)/sizeof(char16_t*),
                                       getter_Copies(title));
    if (NS_FAILED(rv)) return rv;

    // we want to convert string bundle to NCR
    // to ensure they're shown in any charsets
    AppendNonAsciiToNCR(title, buffer);

    buffer.AppendLiteral("</title>\n");    

    // If there is a quote character in the baseUri, then
    // lets not add a base URL.  The reason for this is that
    // if we stick baseUri containing a quote into a quoted
    // string, the quote character will prematurely close
    // the base href string.  This is a fall-back check;
    // that's why it is OK to not use a base rather than
    // trying to play nice and escaping the quotes.  See bug
    // 358128.

    if (baseUri.FindChar('"') == kNotFound)
    {
        // Great, the baseUri does not contain a char that
        // will prematurely close the string.  Go ahead an
        // add a base href.
        buffer.AppendLiteral("<base href=\"");
        nsAdoptingCString htmlEscapedUri(nsEscapeHTML(baseUri.get()));
        buffer.Append(htmlEscapedUri);
        buffer.AppendLiteral("\" />\n");
    }
    else
    {
        NS_ERROR("broken protocol handler didn't escape double-quote.");
    }

    nsCString direction(NS_LITERAL_CSTRING("ltr"));
    nsCOMPtr<nsIXULChromeRegistry> reg =
      mozilla::services::GetXULChromeRegistryService();
    if (reg) {
      bool isRTL = false;
      reg->IsLocaleRTL(NS_LITERAL_CSTRING("global"), &isRTL);
      if (isRTL) {
        direction.AssignLiteral("rtl");
      }
    }

    buffer.AppendLiteral("</head>\n<body dir=\"");
    buffer.Append(direction);
    buffer.AppendLiteral("\">\n<h1>");
    
    const char16_t* formatHeading[] = {
        htmlEscSpec.get()
    };

    rv = mBundle->FormatStringFromName(MOZ_UTF16("DirTitle"),
                                       formatHeading,
                                       sizeof(formatHeading)/sizeof(char16_t*),
                                       getter_Copies(title));
    if (NS_FAILED(rv)) return rv;
    
    AppendNonAsciiToNCR(title, buffer);
    buffer.AppendLiteral("</h1>\n");

    if (!parentStr.IsEmpty()) {
        nsXPIDLString parentText;
        rv = mBundle->GetStringFromName(MOZ_UTF16("DirGoUp"),
                                        getter_Copies(parentText));
        if (NS_FAILED(rv)) return rv;

        buffer.AppendLiteral("<p id=\"UI_goUp\"><a class=\"up\" href=\"");

        nsAdoptingCString htmlParentStr(nsEscapeHTML(parentStr.get()));
        buffer.Append(htmlParentStr);
        buffer.AppendLiteral("\">");
        AppendNonAsciiToNCR(parentText, buffer);
        buffer.AppendLiteral("</a></p>\n");
    }

    if (isSchemeFile) {
        nsXPIDLString showHiddenText;
        rv = mBundle->GetStringFromName(MOZ_UTF16("ShowHidden"),
                                        getter_Copies(showHiddenText));
        if (NS_FAILED(rv)) return rv;

        buffer.AppendLiteral("<p id=\"UI_showHidden\" style=\"display:none\"><label><input type=\"checkbox\" checked onchange=\"updateHidden()\">");
        AppendNonAsciiToNCR(showHiddenText, buffer);
        buffer.AppendLiteral("</label></p>\n");
    }

    buffer.AppendLiteral("<table>\n");

    nsXPIDLString columnText;

    buffer.AppendLiteral(" <thead>\n"
                         "  <tr>\n"
                         "   <th>");

    rv = mBundle->GetStringFromName(MOZ_UTF16("DirColName"),
                                    getter_Copies(columnText));
    if (NS_FAILED(rv)) return rv;
    AppendNonAsciiToNCR(columnText, buffer);
    buffer.AppendLiteral("</th>\n"
                         "   <th>");

    rv = mBundle->GetStringFromName(MOZ_UTF16("DirColSize"),
                                    getter_Copies(columnText));
    if (NS_FAILED(rv)) return rv;
    AppendNonAsciiToNCR(columnText, buffer);
    buffer.AppendLiteral("</th>\n"
                         "   <th colspan=\"2\">");

    rv = mBundle->GetStringFromName(MOZ_UTF16("DirColMTime"),
                                    getter_Copies(columnText));
    if (NS_FAILED(rv)) return rv;
    AppendNonAsciiToNCR(columnText, buffer);
    buffer.AppendLiteral("</th>\n"
                         "  </tr>\n"
                         " </thead>\n");
    buffer.AppendLiteral(" <tbody>\n");

    aBuffer = buffer;
    return rv;
}