mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-08 12:22:34 +00:00
fix for bug #383840: problems when manually importing bookmarks exported from places based bookmark builds
fix for bug #381225: on import, places bookmarks builds attempt to merge in bookmarks.html, where firefox 2 appends bookmarks fix for bug #380449: potential data loss on export of LAST_MODIFIED, DATE_ADDED and ICON_URI attributes r=dietrich
This commit is contained in:
parent
e85c60fcde
commit
73f5809227
@ -102,11 +102,12 @@
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsIParser.h"
|
||||
#include "prprf.h"
|
||||
|
||||
static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
|
||||
|
||||
#define KEY_TOOLBARFOLDER_LOWER "personal_toolbar_folder"
|
||||
#define KEY_BOOKMARKSSMENU_LOWER "bookmarks_menu"
|
||||
#define KEY_BOOKMARKSMENU_LOWER "bookmarks_menu"
|
||||
#define KEY_PLACESROOT_LOWER "places_root"
|
||||
#define KEY_HREF_LOWER "href"
|
||||
#define KEY_FEEDURL_LOWER "feedurl"
|
||||
@ -116,7 +117,6 @@ static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
|
||||
#define KEY_ICON_URI_LOWER "icon_uri"
|
||||
#define KEY_SHORTCUTURL_LOWER "shortcuturl"
|
||||
#define KEY_POST_DATA_LOWER "post_data"
|
||||
#define KEY_ITEM_ID_LOWER "item_id"
|
||||
#define KEY_NAME_LOWER "name"
|
||||
#define KEY_MICSUM_GEN_URI_LOWER "micsum_gen_uri"
|
||||
#define KEY_GENERATED_TITLE_LOWER "generated_title"
|
||||
@ -128,7 +128,7 @@ static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
|
||||
#define POST_DATA_ANNO NS_LITERAL_CSTRING("URIProperties/POSTData")
|
||||
#define GENERATED_TITLE_ANNO NS_LITERAL_CSTRING("bookmarks/generatedTitle")
|
||||
|
||||
#define BOOKMARKSS_MENU_ICON_URI "chrome://browser/skin/places/bookmarksMenu.png"
|
||||
#define BOOKMARKS_MENU_ICON_URI "chrome://browser/skin/places/bookmarksMenu.png"
|
||||
|
||||
// define to get debugging messages on console about import/export
|
||||
//#define DEBUG_IMPORT
|
||||
@ -179,9 +179,6 @@ public:
|
||||
// special. 'ConsumeHeading' resets this.
|
||||
ContainerType mLastContainerType;
|
||||
|
||||
// Container Id, see above
|
||||
PRInt64 mLastContainerId;
|
||||
|
||||
// this contains the text from the last begin tag until now. It is reset
|
||||
// at every begin tag. We can check it when we see a </a>, or </h3>
|
||||
// to see what the text content of that node should be.
|
||||
@ -212,11 +209,10 @@ public:
|
||||
// and the livemark title is known, we can create it.
|
||||
nsCOMPtr<nsIURI> mPreviousFeed;
|
||||
|
||||
void ConsumeHeading(nsAString* aHeading, ContainerType* aContainerType, PRInt64* aContainerId)
|
||||
void ConsumeHeading(nsAString* aHeading, ContainerType* aContainerType)
|
||||
{
|
||||
*aHeading = mPreviousText;
|
||||
*aContainerType = mLastContainerType;
|
||||
*aContainerId = mLastContainerId;
|
||||
mPreviousText.Truncate();
|
||||
}
|
||||
|
||||
@ -371,12 +367,15 @@ protected:
|
||||
// in the hierarchy, to where we find them in the bookmarks file
|
||||
// being imported. This should be set when we are loading
|
||||
// the default places html file, and should be unset when doing
|
||||
// normal imports so that root folders will not get moved when
|
||||
// normal imports so that root folders will not get moved when
|
||||
// importing bookmarks.html files.
|
||||
PRBool mAllowRootChanges;
|
||||
|
||||
// if set, this is an import of initial bookmarks.html content,
|
||||
// so we don't want to kick off HTTP traffic
|
||||
// and we want the imported personal toolbar folder
|
||||
// to be set as the personal toolbar folder. (if not set
|
||||
// we will treat it as a normal folder.)
|
||||
PRBool mIsImportDefaults;
|
||||
|
||||
// If a folder was specified to import into, then ignore flags to put
|
||||
@ -700,7 +699,6 @@ BookmarkContentSink::HandleHeadBegin(const nsIParserNode& node)
|
||||
// the descriptions contained in a <dd>). Neither is any previous head type
|
||||
frame.mPreviousLink = nsnull;
|
||||
frame.mLastContainerType = BookmarkImportFrame::Container_Normal;
|
||||
frame.mLastContainerId = 0;
|
||||
|
||||
// It is syntactically possible for a heading to appear after another heading
|
||||
// but before the <dl> that encloses that folder's contents. This should not
|
||||
@ -727,17 +725,17 @@ BookmarkContentSink::HandleHeadBegin(const nsIParserNode& node)
|
||||
if (!mFolderSpecified) {
|
||||
for (PRInt32 i = 0; i < attrCount; i ++) {
|
||||
if (node.GetKeyAt(i).LowerCaseEqualsLiteral(KEY_TOOLBARFOLDER_LOWER)) {
|
||||
frame.mLastContainerType = BookmarkImportFrame::Container_Toolbar;
|
||||
if (mIsImportDefaults)
|
||||
frame.mLastContainerType = BookmarkImportFrame::Container_Toolbar;
|
||||
break;
|
||||
} else if (node.GetKeyAt(i).LowerCaseEqualsLiteral(KEY_BOOKMARKSSMENU_LOWER)) {
|
||||
frame.mLastContainerType = BookmarkImportFrame::Container_Menu;
|
||||
} else if (node.GetKeyAt(i).LowerCaseEqualsLiteral(KEY_BOOKMARKSMENU_LOWER)) {
|
||||
if (mIsImportDefaults)
|
||||
frame.mLastContainerType = BookmarkImportFrame::Container_Menu;
|
||||
break;
|
||||
} else if (node.GetKeyAt(i).LowerCaseEqualsLiteral(KEY_PLACESROOT_LOWER)) {
|
||||
frame.mLastContainerType = BookmarkImportFrame::Container_Places;
|
||||
if (mIsImportDefaults)
|
||||
frame.mLastContainerType = BookmarkImportFrame::Container_Places;
|
||||
break;
|
||||
} else if (node.GetKeyAt(i).LowerCaseEqualsLiteral(KEY_ITEM_ID_LOWER)) {
|
||||
frame.mLastContainerId =
|
||||
ConvertImportedIdToInternalId(NS_ConvertUTF16toUTF8(node.GetValueAt(i)));
|
||||
} else if (node.GetKeyAt(i).LowerCaseEqualsLiteral(KEY_DATE_ADDED_LOWER)) {
|
||||
frame.mPreviousDateAdded =
|
||||
ConvertImportedDateToInternalDate(NS_ConvertUTF16toUTF8(node.GetValueAt(i)));
|
||||
@ -820,8 +818,6 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
|
||||
postData = node.GetValueAt(i);
|
||||
} else if (key.LowerCaseEqualsLiteral(KEY_WEB_PANEL_LOWER)) {
|
||||
webPanel = node.GetValueAt(i);
|
||||
} else if (key.LowerCaseEqualsLiteral(KEY_ITEM_ID_LOWER)) {
|
||||
itemId = node.GetValueAt(i);
|
||||
} else if (key.LowerCaseEqualsLiteral(KEY_MICSUM_GEN_URI_LOWER)) {
|
||||
micsumGenURI = node.GetValueAt(i);
|
||||
} else if (key.LowerCaseEqualsLiteral(KEY_GENERATED_TITLE_LOWER)) {
|
||||
@ -1072,67 +1068,34 @@ BookmarkContentSink::HandleSeparator(const nsIParserNode& aNode)
|
||||
{
|
||||
BookmarkImportFrame& frame = CurFrame();
|
||||
|
||||
// check for pre-existing id
|
||||
PRInt64 id = 0;
|
||||
nsAutoString itemIdAttr;
|
||||
// create the separator
|
||||
|
||||
#ifdef DEBUG_IMPORT
|
||||
PrintNesting();
|
||||
printf("--------\n");
|
||||
#endif
|
||||
|
||||
PRInt64 itemId;
|
||||
mBookmarksService->InsertSeparator(frame.mContainerID,
|
||||
mBookmarksService->DEFAULT_INDEX,
|
||||
&itemId);
|
||||
// Import separator title if set
|
||||
nsAutoString name;
|
||||
PRInt32 attrCount = aNode.GetAttributeCount();
|
||||
for (PRInt32 i = 0; i < attrCount; i ++) {
|
||||
const nsAString& key = aNode.GetKeyAt(i);
|
||||
if (key.LowerCaseEqualsLiteral(KEY_ITEM_ID_LOWER)) {
|
||||
itemIdAttr = aNode.GetValueAt(i);
|
||||
}
|
||||
if (key.LowerCaseEqualsLiteral(KEY_NAME_LOWER))
|
||||
name = aNode.GetValueAt(i);
|
||||
}
|
||||
name.Trim(kWhitespace);
|
||||
|
||||
itemIdAttr.Trim(kWhitespace);
|
||||
id = ConvertImportedIdToInternalId(NS_ConvertUTF16toUTF8(itemIdAttr));
|
||||
if (!name.IsEmpty())
|
||||
mBookmarksService->SetItemTitle(itemId, name);
|
||||
|
||||
// check id validity
|
||||
if (id > 0) {
|
||||
PRInt64 parent;
|
||||
nsresult rv = mBookmarksService->GetFolderIdForItem(id, &parent);
|
||||
if (NS_FAILED(rv) || parent != frame.mContainerID) {
|
||||
id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (id > 0) {
|
||||
PRUint16 type;
|
||||
nsresult rv = mBookmarksService->GetItemType(id, &type);
|
||||
if (NS_FAILED(rv) || type != mBookmarksService->TYPE_SEPARATOR) {
|
||||
id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == 0) {
|
||||
// create the separator
|
||||
|
||||
#ifdef DEBUG_IMPORT
|
||||
PrintNesting();
|
||||
printf("--------\n");
|
||||
#endif
|
||||
|
||||
PRInt64 itemId;
|
||||
mBookmarksService->InsertSeparator(frame.mContainerID,
|
||||
mBookmarksService->DEFAULT_INDEX,
|
||||
&itemId);
|
||||
// Import separator title if set
|
||||
nsAutoString name;
|
||||
PRInt32 attrCount = aNode.GetAttributeCount();
|
||||
for (PRInt32 i = 0; i < attrCount; i ++) {
|
||||
const nsAString& key = aNode.GetKeyAt(i);
|
||||
if (key.LowerCaseEqualsLiteral(KEY_NAME_LOWER))
|
||||
name = aNode.GetValueAt(i);
|
||||
}
|
||||
name.Trim(kWhitespace);
|
||||
|
||||
if (!name.IsEmpty())
|
||||
mBookmarksService->SetItemTitle(itemId, name);
|
||||
|
||||
// Note: we do not need to import ADD_DATE or LAST_MODIFIED for separators
|
||||
// because pre-Places bookmarks does not support them.
|
||||
// and we can't write them out because attributes other than NAME make Firefox 2.x
|
||||
// crash/hang - see bug #381129
|
||||
}
|
||||
// Note: we do not need to import ADD_DATE or LAST_MODIFIED for separators
|
||||
// because pre-Places bookmarks does not support them.
|
||||
// and we can't write them out because attributes other than NAME
|
||||
// will make Firefox 2.x crash/hang - see bug #381129
|
||||
}
|
||||
|
||||
|
||||
@ -1149,73 +1112,58 @@ BookmarkContentSink::NewFrame()
|
||||
PRInt64 ourID = 0;
|
||||
nsString containerName;
|
||||
BookmarkImportFrame::ContainerType containerType;
|
||||
CurFrame().ConsumeHeading(&containerName, &containerType, &ourID);
|
||||
CurFrame().ConsumeHeading(&containerName, &containerType);
|
||||
|
||||
PRBool updateFolder = PR_FALSE;
|
||||
|
||||
if (ourID > 0) {
|
||||
// Check that folder id is valid.
|
||||
PRInt64 ourParentId;
|
||||
rv = mBookmarksService->GetFolderIdForItem(ourID, &ourParentId);
|
||||
if (NS_FAILED(rv) || ourParentId != CurFrame().mContainerID) {
|
||||
ourID = 0;
|
||||
}
|
||||
|
||||
switch (containerType) {
|
||||
case BookmarkImportFrame::Container_Normal:
|
||||
// append a new folder
|
||||
rv = mBookmarksService->CreateFolder(CurFrame().mContainerID,
|
||||
containerName,
|
||||
mBookmarksService->DEFAULT_INDEX,
|
||||
&ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
case BookmarkImportFrame::Container_Places:
|
||||
// places root, never reparent here, when we're building the initial
|
||||
// hierarchy, it will only be defined at the top level
|
||||
rv = mBookmarksService->GetPlacesRoot(&ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
case BookmarkImportFrame::Container_Menu:
|
||||
// menu root
|
||||
rv = mBookmarksService->GetBookmarksRoot(&ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (mAllowRootChanges) {
|
||||
updateFolder = PR_TRUE;
|
||||
rv = SetFaviconForFolder(ourID, NS_LITERAL_CSTRING(BOOKMARKS_MENU_ICON_URI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
break;
|
||||
case BookmarkImportFrame::Container_Toolbar:
|
||||
// get toolbar folder
|
||||
PRInt64 toolbarFolder;
|
||||
rv = mBookmarksService->GetToolbarFolder(&toolbarFolder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!toolbarFolder) {
|
||||
// create new folder
|
||||
rv = mBookmarksService->CreateFolder(CurFrame().mContainerID,
|
||||
containerName,
|
||||
mBookmarksService->DEFAULT_INDEX, &ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// there's no toolbar folder, so make us the toolbar folder
|
||||
rv = mBookmarksService->SetToolbarFolder(ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
ourID = toolbarFolder;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown container type");
|
||||
}
|
||||
|
||||
if (ourID == 0) {
|
||||
switch (containerType) {
|
||||
case BookmarkImportFrame::Container_Normal:
|
||||
// regular folder: use an existing folder if that name already exists
|
||||
rv = mBookmarksService->GetChildFolder(CurFrame().mContainerID,
|
||||
containerName, &ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (ourID == 0) {
|
||||
// need to append a new folder
|
||||
rv = mBookmarksService->CreateFolder(CurFrame().mContainerID,
|
||||
containerName,
|
||||
mBookmarksService->DEFAULT_INDEX, &ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
break;
|
||||
case BookmarkImportFrame::Container_Places:
|
||||
// places root, never reparent here, when we're building the initial
|
||||
// hierarchy, it will only be defined at the top level
|
||||
rv = mBookmarksService->GetPlacesRoot(&ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
case BookmarkImportFrame::Container_Menu:
|
||||
// menu root
|
||||
rv = mBookmarksService->GetBookmarksRoot(&ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (mAllowRootChanges) {
|
||||
updateFolder = PR_TRUE;
|
||||
rv = SetFaviconForFolder(ourID, NS_LITERAL_CSTRING(BOOKMARKSS_MENU_ICON_URI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
break;
|
||||
case BookmarkImportFrame::Container_Toolbar:
|
||||
// get toolbar folder
|
||||
PRInt64 toolbarFolder;
|
||||
rv = mBookmarksService->GetToolbarFolder(&toolbarFolder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!toolbarFolder) {
|
||||
// create new folder
|
||||
rv = mBookmarksService->CreateFolder(CurFrame().mContainerID,
|
||||
containerName,
|
||||
mBookmarksService->DEFAULT_INDEX, &ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// there's no toolbar folder, so make us the toolbar folder
|
||||
rv = mBookmarksService->SetToolbarFolder(ourID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
ourID = toolbarFolder;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown container type");
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_IMPORT
|
||||
PrintNesting();
|
||||
printf("Folder %lld \'%s\'", ourID, NS_ConvertUTF16toUTF8(containerName).get());
|
||||
@ -1315,10 +1263,12 @@ BookmarkContentSink::SetFaviconForURI(nsIURI* aPageURI, nsIURI* aIconURI,
|
||||
faviconSpec.AssignLiteral("http://www.mozilla.org/2005/made-up-favicon/");
|
||||
faviconSpec.AppendInt(serialNumber);
|
||||
faviconSpec.AppendLiteral("-");
|
||||
faviconSpec.AppendInt(PR_Now()); // casting from PRInt64 -> PRInt32, data loss, fix me
|
||||
char buf[32];
|
||||
PR_snprintf(buf, sizeof(buf), "%lld", PR_Now());
|
||||
faviconSpec.Append(buf);
|
||||
rv = NS_NewURI(getter_AddRefs(faviconURI), faviconSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
serialNumber ++;
|
||||
serialNumber++;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> dataURI;
|
||||
@ -1477,7 +1427,7 @@ static const char kDescriptionIntro[] = "<DD>";
|
||||
static const char kDescriptionClose[] = NS_LINEBREAK;
|
||||
|
||||
static const char kPlacesRootAttribute[] = " PLACES_ROOT=\"true\"";
|
||||
static const char kBookmarksRootAttribute[] = " BOOKMARKSS_MENU=\"true\"";
|
||||
static const char kBookmarksRootAttribute[] = " BOOKMARKS_MENU=\"true\"";
|
||||
static const char kToolbarFolderAttribute[] = " PERSONAL_TOOLBAR_FOLDER=\"true\"";
|
||||
static const char kIconAttribute[] = " ICON=\"";
|
||||
static const char kIconURIAttribute[] = " ICON_URI=\"";
|
||||
@ -1628,11 +1578,15 @@ WriteDateAttribute(const char aAttributeStart[], PRInt32 aLength, PRTime aAttrib
|
||||
PRUint32 dummy;
|
||||
nsresult rv = aOutput->Write(aAttributeStart, aLength, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// in bookmarks.html this value is in seconds, not microseconds
|
||||
aAttributeValue /= 1000000;
|
||||
|
||||
// write attribute value
|
||||
nsCAutoString dateInSeconds;
|
||||
aAttributeValue/= 1000000; // in bookmarks.html this value is in seconds, not microseconds
|
||||
dateInSeconds.AppendInt(aAttributeValue); // casting from PRInt64 -> PRInt32, data loss, fix me
|
||||
rv = aOutput->Write(dateInSeconds.get(), dateInSeconds.Length(), &dummy);
|
||||
char dateInSeconds[32];
|
||||
PR_snprintf(dateInSeconds, sizeof(dateInSeconds), "%lld", aAttributeValue);
|
||||
rv = aOutput->Write(dateInSeconds, strlen(dateInSeconds), &dummy);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return aOutput->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
|
||||
}
|
||||
@ -1728,17 +1682,7 @@ nsPlacesImportExportService::WriteContainerHeader(nsINavHistoryResultNode* aFold
|
||||
rv = aOutput->Write(kToolbarFolderAttribute, sizeof(kToolbarFolderAttribute)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// write id as ITEM_ID as non-rdf IDs can confuse Firefox 2
|
||||
rv = aOutput->Write(kItemIdAttribute, sizeof(kItemIdAttribute)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCAutoString itemIdAttr;
|
||||
itemIdAttr.AppendInt(folderId); // casting from PRInt64 -> PRInt32, data loss, fix me
|
||||
rv = aOutput->Write(itemIdAttr.get(), itemIdAttr.Length(), &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aOutput->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
||||
// favicon (most folders won't have one)
|
||||
nsCOMPtr<nsIURI> folderURI;
|
||||
rv = mBookmarksService->GetFolderURI(folderId, getter_AddRefs(folderURI));
|
||||
@ -1897,16 +1841,6 @@ nsPlacesImportExportService::WriteItem(nsINavHistoryResultNode* aItem,
|
||||
rv = aItem->GetItemId(&itemId);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// write id as ITEM_ID as non-rdf IDs can confuse Firefox 2
|
||||
rv = aOutput->Write(kItemIdAttribute, sizeof(kItemIdAttribute)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCAutoString itemIdAttr;
|
||||
itemIdAttr.AppendInt(itemId); // casting from PRInt64 -> PRInt32, data loss, fix me
|
||||
rv = aOutput->Write(itemIdAttr.get(), itemIdAttr.Length(), &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aOutput->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// keyword (shortcuturl)
|
||||
nsAutoString keyword;
|
||||
rv = mBookmarksService->GetKeywordForBookmark(itemId, keyword);
|
||||
@ -2071,16 +2005,6 @@ nsPlacesImportExportService::WriteLivemark(nsINavHistoryResultNode* aFolder, con
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// write id as ITEM_ID as non-rdf IDs can confuse Firefox 2
|
||||
rv = aOutput->Write(kItemIdAttribute, sizeof(kItemIdAttribute)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCAutoString itemIdAttr;
|
||||
itemIdAttr.AppendInt(folderId); // casting from PRInt64 -> PRInt32, data loss, fix me
|
||||
rv = aOutput->Write(itemIdAttr.get(), itemIdAttr.Length(), &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aOutput->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// '>'
|
||||
rv = aOutput->Write(kCloseAngle, sizeof(kCloseAngle)-1, &dummy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
Loading…
Reference in New Issue
Block a user