NS_IMETHODIMP
sbRemoteSiteLibraryResource::GetProperty( const nsAString &aID,
                                          nsAString &_retval )
{
  LOG_RES(( "sbRemoteSiteLibraryResource::GetProperty(%s)",
            NS_LossyConvertUTF16toASCII(aID).get() ));

  // First call the base class impl and see what it says. contentURL will get
  // denied as it is not remoteReadable by default, we special case for site
  // objects
  nsresult rv = sbRemoteLibraryResource::GetProperty( aID, _retval );
  if ( NS_SUCCEEDED(rv) || !aID.EqualsLiteral(SB_PROPERTY_CONTENTURL) ) {
    return rv;
  }

  // Do some special checking for contentURL properties. Sites should be able
  // to access the contentURLs for tracks that aren't on the hard drive.
  nsString contentURL;
  rv = mMediaItem->GetProperty( aID, contentURL );
  NS_ENSURE_SUCCESS( rv, rv );

  if ( StringBeginsWith( contentURL, NS_LITERAL_STRING("file:") ) ) {
    LOG_RES(( "sbRemoteSiteLibraryResource::GetProperty() - "
              "Disallowing access to 'file:' URI from contentURL property" ));
    _retval.AssignLiteral("__BLOCKED__");
    return NS_ERROR_FAILURE;
  }
  LOG_RES(( "sbRemoteSiteLibraryResource::GetProperty() - "
            "Allowing access to non-file contentURL to site item/list/lib: %s",
            NS_LossyConvertUTF16toASCII(contentURL).get() ));

  _retval.Assign(contentURL);
  return NS_OK;
}
// ----------------------------------------------------------------------------
//
//                          sbILibraryResource
//
// ----------------------------------------------------------------------------
NS_IMETHODIMP
sbRemoteLibraryResource::GetProperty( const nsAString &aID,
                                      nsAString &_retval )
{
  NS_ENSURE_TRUE( mMediaItem, NS_ERROR_NULL_POINTER );
  LOG_RES(( "sbRemoteLibraryResource::GetProperty(%s)",
             NS_LossyConvertUTF16toASCII(aID).get() ));

  nsresult rv;

  // get the property manager service
  nsCOMPtr<sbIPropertyManager> propertyManager =
      do_GetService( "@songbirdnest.com/Songbird/Properties/PropertyManager;1",
                     &rv );
  NS_ENSURE_SUCCESS( rv, rv );

  // get the property info for the property being requested
  nsCOMPtr<sbIPropertyInfo> propertyInfo;
  rv = propertyManager->GetPropertyInfo( aID, getter_AddRefs(propertyInfo) );
  NS_ENSURE_SUCCESS( rv, rv );

  // ask if this property is remotely readable
  bool readable;
  rv = propertyInfo->GetRemoteReadable(&readable);
  NS_ENSURE_SUCCESS( rv, rv );

  // well, is it readable?
  if (!readable) {
    LOG_RES(( "Attempting to get a property's (%s) value that is not allowed "
              "to be read from the remote API!",
              NS_LossyConvertUTF16toASCII(aID).get() ));
    // if not return an error
    return NS_ERROR_FAILURE;
  }

  // readable property
  nsString propVal;
  rv = mMediaItem->GetProperty( aID, propVal );
  NS_ENSURE_SUCCESS( rv, rv );

  // Protect against exposing file:// uris to the world.
  if ( !aID.EqualsLiteral(SB_PROPERTY_ORIGINURL) ||
       !aID.EqualsLiteral(SB_PROPERTY_COPYRIGHTURL) ||
       !aID.EqualsLiteral(SB_PROPERTY_PRIMARYIMAGEURL) ) {

    if ( StringBeginsWith( propVal, NS_LITERAL_STRING("file:") ) ) {
      LOG_RES(( "sbRemoteLibraryResource::GetProperty() - "
                "Disallowing access to 'file:' URI." ));
      // Assign a dummy signal value
      propVal.AssignLiteral("__BLOCKED__");
    } else {
      LOG_RES(( "sbRemoteLibraryResource::GetProperty() - "
                "Allowing access to non-file value: %s",
                NS_LossyConvertUTF16toASCII(propVal).get() ));
    }
  }

  _retval.Assign(propVal);
  return NS_OK;
}
sbRemoteSiteLibraryResource::sbRemoteSiteLibraryResource( sbRemotePlayer *aRemotePlayer,
                                                          sbIMediaItem *aMediaItem ) :
  sbRemoteLibraryResource( aRemotePlayer, aMediaItem )
{
  NS_ASSERTION( aRemotePlayer, "Null remote player!" );
  NS_ASSERTION( aMediaItem, "Null media item!" );

  LOG_RES(("sbRemoteSiteLibraryResource::sbRemoteSiteLibraryResource()"));
}
sbRemoteLibraryResource::sbRemoteLibraryResource( sbRemotePlayer *aRemotePlayer,
                                                  sbIMediaItem *aMediaItem ) :
  mRemotePlayer(aRemotePlayer),
  mMediaItem(aMediaItem)
{
  NS_ASSERTION( aRemotePlayer, "Null remote player!" );
  NS_ASSERTION( aMediaItem, "Null media item!" );

#ifdef PR_LOGGING
  if (!gRemoteLibResLog) {
    gRemoteLibResLog = PR_NewLogModule("sbRemoteLibraryResource");
  }
  LOG_RES(("sbRemoteLibraryResource::sbRemoteLibraryResource()"));
#endif
}
NS_IMETHODIMP
sbRemoteLibraryResource::SetProperties( sbIPropertyArray *aProperties )
{
  LOG_RES(("sbRemoteLibraryResource::SetProperties()"));
  NS_ENSURE_ARG_POINTER( aProperties );
  NS_ASSERTION( mMediaItem, "SetProperties called before Initialization" ); 

  nsresult rv = mMediaItem->SetProperties(aProperties);
  NS_ENSURE_SUCCESS( rv, rv );

  nsCOMPtr<sbILibrary> library;
  rv = mMediaItem->GetLibrary( getter_AddRefs(library) );
  NS_ENSURE_SUCCESS( rv, rv );

  mRemotePlayer->GetNotificationManager()->Action(
    sbRemoteNotificationManager::eEditedItems, library );

  return NS_OK;
}
sbRemoteLibraryResource::~sbRemoteLibraryResource() {
  LOG_RES(("sbRemoteLibraryResource::~sbRemoteLibraryResource()"));
}
NS_IMETHODIMP
sbRemoteLibraryResource::SetProperty( const nsAString &aID,
                                      const nsAString &aValue )
{
  LOG_RES(( "sbRemoteLibraryResource::SetProperty( %s, %s )",
            NS_LossyConvertUTF16toASCII(aID).get(),
            NS_LossyConvertUTF16toASCII(aValue).get() ));

  NS_ASSERTION( mMediaItem, "SetProperty called before Initialization" ); 

  nsresult rv = NS_OK;

  // get the property manager service
  nsCOMPtr<sbIPropertyManager> propertyManager =
      do_GetService( "@songbirdnest.com/Songbird/Properties/PropertyManager;1",
                     &rv );
  NS_ENSURE_SUCCESS( rv, rv );

  // Check to see if we have the property first, if not we must create it with
  // the right settings so websites can modify it.
  bool hasProp;
  rv = propertyManager->HasProperty( aID, &hasProp );

  // get the property info for the property being requested - this will create
  // it if it didn't already exist.
  nsCOMPtr<sbIPropertyInfo> propertyInfo;
  rv = propertyManager->GetPropertyInfo( aID, getter_AddRefs(propertyInfo) );
  NS_ENSURE_SUCCESS( rv, rv );

  // check to see if the prop already existed or if we created it
  if (hasProp) {
    // ask if this property is remotely writable
    bool writable = PR_FALSE;
    rv = propertyInfo->GetRemoteWritable(&writable);
    NS_ENSURE_SUCCESS( rv, rv );

    // well, is it writeable?
    if (!writable) {
      // if not return an error
      LOG_RES(( "Attempting to set a property's (%s) value that is not allowed "
                "to be set from the remote API!",
                NS_LossyConvertUTF16toASCII(aID).get() ));
      return NS_ERROR_FAILURE;
    }
  }
  else {
    // we created a new property in the system so enable remote write/read
    rv = propertyInfo->SetRemoteWritable(PR_TRUE);
    NS_ENSURE_SUCCESS( rv, rv );

    rv = propertyInfo->SetRemoteReadable(PR_TRUE);
    NS_ENSURE_SUCCESS( rv, rv );
  }

  // it all looks ok, pass this request on to the real media item
  rv = mMediaItem->SetProperty( aID, aValue );
  NS_ENSURE_SUCCESS( rv, rv );

  nsCOMPtr<sbILibrary> library;
  rv = mMediaItem->GetLibrary( getter_AddRefs(library) );
  NS_ENSURE_SUCCESS( rv, rv );

  mRemotePlayer->GetNotificationManager()->Action(
    sbRemoteNotificationManager::eEditedItems, library );

  return NS_OK;
}
Exemple #8
0
/*
* Loads all resources from the stream, except images, binaries and sprites.
*/
bool Syscall::loadResources(Stream& file, const char* aFilename)  {
    bool hasResources = true;
    if(!file.isOpen())
        hasResources = false;
    else {
        int len, pos;
        TEST(file.length(len));
        TEST(file.tell(pos));
        if(len == pos)
            hasResources = false;
    }
    if(!hasResources/* && aFilename != NULL*/) {
        resources.init(0);
        return true;
    }

#define MATCH_BYTE(c) { DAR_UBYTE(b); if(b != c) { FAIL; } }
    MATCH_BYTE('M');
    MATCH_BYTE('A');
    MATCH_BYTE('R');
    MATCH_BYTE('S');

    DAR_UVINT(nResources);
    DAR_UVINT(rSize);
    resources.init(nResources);

    resourcesCount = nResources;
    resourceOffset = new int[nResources];
    resourceSize = new int[nResources];
    resourceType = new int[nResources];
    resourcesFilename = new char[strlen(aFilename) + 1];
    strcpy(resourcesFilename, aFilename);

    // rI is the resource index.
    int rI = 1;

    while(true) {
        DAR_UBYTE(type);
        if(type == 0)
            break;

        //dispose flag

        DAR_UVINT(size);
        LOG_RES("Type %i, size %i\n", type, size);

        int index = rI - 1;

        TEST(file.tell(resourceOffset[index]));
        resourceSize[index] = size;
        resourceType[index] = type;

        switch(type) {
        case RT_UBIN:
        {
            int pos;
            MYASSERT(aFilename, ERR_RES_LOAD_UBIN);
            TEST(file.tell(pos));
#ifndef _android
            ROOM(resources.dadd_RT_BINARY(rI,
                                          new LimitedFileStream(aFilename, pos, size)));
#else
            // Android loads ubins by using JNI.
            loadUBinary(rI, pos, size);
            ROOM(resources.dadd_RT_BINARY(rI,
                                          new LimitedFileStream(
                                              aFilename,
                                              pos,
                                              size,
                                              getJNIEnvironment(),
                                              getJNIThis())));
#endif
            TEST(file.seek(Seek::Current, size));
        }
        break;
        case RT_PLACEHOLDER:
            ROOM(resources.dadd_RT_PLACEHOLDER(rI, NULL));
            break;
        case RT_LABEL:
        {
            MemStream b(size);
            TEST(file.readFully(b));
            ROOM(resources.dadd_RT_LABEL(rI, new Label((const char*)b.ptr(), rI)));
        }
        break;

#ifdef LOGGING_ENABLED
        case 99:  //testtype
#define DUMP_UVI { DAR_UVINT(u); LOG_RES("u %i\n", u); }
#define DUMP_SVI { DAR_SVINT(s); LOG_RES("s %i\n", s); }
            DUMP_UVI;
            DUMP_UVI;
            DUMP_UVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            break;
#endif
        default:
            TEST(file.seek(Seek::Current, size));
        }

        rI++;
    }
    if(rI != nResources + 1) {
        LOG("rI %i, nR %i\n", rI, nResources);
        BIG_PHAT_ERROR(ERR_RES_FILE_INCONSISTENT);
    }
    LOG_RES("ResLoad complete\n");
    return true;
}
Exemple #9
0
/*
* Loads all resources from the given buffer.
*/
bool Syscall::loadResourcesFromBuffer(Stream& file, const char* aFilename)  {
    bool hasResources = true;
    if(!file.isOpen())
        hasResources = false;
    else {
        int len, pos;
        TEST(file.length(len));
        TEST(file.tell(pos));
        if(len == pos)
            hasResources = false;
    }
    if(!hasResources/* && aFilename != NULL*/) {
        resources.init(0);
        return true;
    }

#define MATCH_BYTE(c) { DAR_UBYTE(b); if(b != c) { FAIL; } }
    MATCH_BYTE('M');
    MATCH_BYTE('A');
    MATCH_BYTE('R');
    MATCH_BYTE('S');

    DAR_UVINT(nResources);
    DAR_UVINT(rSize);
    resources.init(nResources);

    // rI is the resource index.
    int rI = 1;

    while(true) {
        DAR_UBYTE(type);
        if(type == 0)
            break;

        //dispose flag

        DAR_UVINT(size);
        LOG_RES("Type %i, size %i\n", type, size);

        switch(type) {
        case RT_BINARY:
        {
#ifndef _android
            MemStream* ms = new MemStream(size);
#else
            char* b = loadBinary(rI, size);
            MemStream* ms = new MemStream(b, size);
#endif
            TEST(file.readFully(*ms));
            ROOM(resources.dadd_RT_BINARY(rI, ms));
#ifdef _android
            checkAndStoreAudioResource(rI);
#endif
        }
        break;
        case RT_UBIN:
        {
            int pos;
            MYASSERT(aFilename, ERR_RES_LOAD_UBIN);
            TEST(file.tell(pos));
#ifndef _android
            ROOM(resources.dadd_RT_BINARY(rI,
                                          new LimitedFileStream(aFilename, pos, size)));
#else
            // Android loads ubins by using JNI.
            loadUBinary(rI, pos, size);
            ROOM(resources.dadd_RT_BINARY(rI,
                                          new LimitedFileStream(
                                              aFilename,
                                              pos,
                                              size,
                                              getJNIEnvironment(),
                                              getJNIThis())));
#endif
            TEST(file.seek(Seek::Current, size));
        }
        break;
        case RT_PLACEHOLDER:
            ROOM(resources.dadd_RT_PLACEHOLDER(rI, NULL));
            break;
        case RT_IMAGE:
        {
            MemStream b(size);
            TEST(file.readFully(b));
#ifndef _android
            // On all platforms except Android, we load and add
            // the image data. "dadd" means "delete and add",
            // and is defined in runtimes\cpp\base\ResourceArray.h
            RT_IMAGE_Type* image = loadImage(b);
            if(!image)
                BIG_PHAT_ERROR(ERR_IMAGE_LOAD_FAILED);
            ROOM(resources.dadd_RT_IMAGE(rI, image));
#else
            // On Android images are stored on the Java side.
            // Here we allocate a dummy array (real image is
            // in a table in Java) so that the resource handling,
            // like deleting resources, will work also on Android.
            // The actual image will be garbage collected on
            // Android when a resource is replaced in the Java table.
            ROOM(resources.dadd_RT_IMAGE(rI, new int[1]));
            int pos;
            file.tell(pos);
            loadImage(
                rI,
                pos - size,
                size,
                Base::gSyscall->getReloadHandle());
#endif
        }
        break;
        case RT_SPRITE:
        {
            DAR_USHORT(indexSource);
            DAR_USHORT(left);
            DAR_USHORT(top);
            DAR_USHORT(width);
            DAR_USHORT(height);
            DAR_SHORT(cx);
            DAR_SHORT(cy);
#ifndef _android
            ROOM(resources.dadd_RT_IMAGE(rI, loadSprite(resources.get_RT_IMAGE(indexSource),
                                         left, top, width, height, cx, cy)));
#endif
        }
        break;
        case RT_LABEL:
        {
            MemStream b(size);
            TEST(file.readFully(b));
            ROOM(resources.dadd_RT_LABEL(rI, new Label((const char*)b.ptr(), rI)));
        }
        break;

#ifdef LOGGING_ENABLED
        case 99:  //testtype
#define DUMP_UVI { DAR_UVINT(u); LOG_RES("u %i\n", u); }
#define DUMP_SVI { DAR_SVINT(s); LOG_RES("s %i\n", s); }
            DUMP_UVI;
            DUMP_UVI;
            DUMP_UVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            DUMP_SVI;
            break;
#endif
        default:
            TEST(file.seek(Seek::Current, size));
        }
        rI++;
    }
    if(rI != nResources + 1) {
        LOG("rI %i, nR %i\n", rI, nResources);
        BIG_PHAT_ERROR(ERR_RES_FILE_INCONSISTENT);
    }
    LOG_RES("ResLoad complete\n");
    return true;
}