Bug 1333631 - Disallow nsIFile::GetNativeTarget on Windows. r=froydnj
MozReview-Commit-ID: 4igXHPtQu4x
--- a/xpcom/idl-parser/xpidl/header.py
+++ b/xpcom/idl-parser/xpidl/header.py
@@ -380,33 +380,35 @@ def write_interface(iface, fd):
'signed': (not basetype.signed) and 'U' or ''})
fd.write(",\n".join(enums))
fd.write("\n };\n\n")
def write_method_decl(m):
printComments(fd, m.doccomments, ' ')
fd.write(" /* %s */\n" % m.toIDL())
- fd.write(" %s = 0;\n\n" % methodAsNative(m))
+ suffix = " = delete" if m.deleted else " = 0"
+ fd.write(" %s%s;\n\n" % (methodAsNative(m), suffix))
def write_attr_decl(a):
printComments(fd, a.doccomments, ' ')
fd.write(" /* %s */\n" % a.toIDL())
- fd.write(" %s = 0;\n" % attributeAsNative(a, True))
+ suffix = " = delete" if a.deleted else " = 0"
+ fd.write(" %s%s;\n" % (attributeAsNative(a, True), suffix))
if a.infallible:
fd.write(attr_infallible_tmpl %
{'realtype': a.realtype.nativeType('in'),
'nativename': attributeNativeName(a, getter=True),
'args': '' if not a.implicit_jscontext else 'JSContext* cx',
'argnames': '' if not a.implicit_jscontext else 'cx, '})
if not a.readonly:
- fd.write(" %s = 0;\n" % attributeAsNative(a, False))
+ fd.write(" %s%s;\n" % (attributeAsNative(a, False), suffix))
fd.write("\n")
defname = iface.name.upper()
if iface.name[0:2] == 'ns':
defname = 'NS_' + defname[2:]
names = uuid_decoder.match(iface.attributes.uuid).groupdict()
m3str = names['m3'] + names['m4']
@@ -459,72 +461,79 @@ def write_interface(iface, fd):
fd.write(iface_epilog % names)
def writeDeclaration(fd, iface, virtual):
declType = "NS_IMETHOD" if virtual else "nsresult"
suffix = " override" if virtual else ""
for member in iface.members:
if isinstance(member, xpidl.Attribute):
+ suffix2 = " = delete" if member.deleted else ""
if member.infallible:
fd.write("\\\n using %s::%s; " % (iface.name, attributeNativeName(member, True)))
- fd.write("\\\n %s%s; " % (attributeAsNative(member, True, declType), suffix))
+ fd.write("\\\n %s%s%s; " % (attributeAsNative(member, True, declType), suffix, suffix2))
if not member.readonly:
- fd.write("\\\n %s%s; " % (attributeAsNative(member, False, declType), suffix))
+ fd.write("\\\n %s%s%s; " % (attributeAsNative(member, False, declType), suffix, suffix2))
elif isinstance(member, xpidl.Method):
- fd.write("\\\n %s%s; " % (methodAsNative(member, declType), suffix))
+ suffix2 = " = delete" if member.deleted else ""
+ fd.write("\\\n %s%s%s; " % (methodAsNative(member, declType), suffix, suffix2))
if len(iface.members) == 0:
fd.write('\\\n /* no methods! */')
elif not member.kind in ('attribute', 'method'):
fd.write('\\')
writeDeclaration(fd, iface, True);
fd.write(iface_nonvirtual % names)
writeDeclaration(fd, iface, False);
fd.write(iface_forward % names)
- def emitTemplate(forward_infallible, tmpl, tmpl_notxpcom=None):
+ def emitTemplate(forward_infallible, tmpl_normal, tmpl_notxpcom=None, tmpl_deleted=None):
if tmpl_notxpcom is None:
- tmpl_notxpcom = tmpl
+ tmpl_notxpcom = tmpl_normal
for member in iface.members:
if isinstance(member, xpidl.Attribute):
if forward_infallible and member.infallible:
fd.write("\\\n using %s::%s; " % (iface.name, attributeNativeName(member, True)))
+ tmpl = tmpl_deleted if member.deleted else tmpl_normal
fd.write(tmpl % {'asNative': attributeAsNative(member, True),
'nativeName': attributeNativeName(member, True),
'paramList': attributeParamNames(member)})
if not member.readonly:
fd.write(tmpl % {'asNative': attributeAsNative(member, False),
'nativeName': attributeNativeName(member, False),
'paramList': attributeParamNames(member)})
elif isinstance(member, xpidl.Method):
+ tmpl = tmpl_deleted if member.deleted else tmpl_normal
if member.notxpcom:
fd.write(tmpl_notxpcom % {'asNative': methodAsNative(member),
'nativeName': methodNativeName(member),
'paramList': paramlistNames(member)})
else:
fd.write(tmpl % {'asNative': methodAsNative(member),
'nativeName': methodNativeName(member),
'paramList': paramlistNames(member)})
if len(iface.members) == 0:
fd.write('\\\n /* no methods! */')
elif not member.kind in ('attribute', 'method'):
fd.write('\\')
emitTemplate(True,
- "\\\n %(asNative)s override { return _to %(nativeName)s(%(paramList)s); } ")
+ "\\\n %(asNative)s override { return _to %(nativeName)s(%(paramList)s); } ",
+ None,
+ "\\\n %(asNative)s override = delete; ")
fd.write(iface_forward_safe % names)
# Don't try to safely forward notxpcom functions, because we have no
# sensible default error return. Instead, the caller will have to
# implement them.
emitTemplate(False,
"\\\n %(asNative)s override { return !_to ? NS_ERROR_NULL_POINTER : _to->%(nativeName)s(%(paramList)s); } ",
- "\\\n %(asNative)s override; ")
+ "\\\n %(asNative)s override; ",
+ "\\\n %(asNative)s override = delete; ")
fd.write(iface_template_prolog % names)
for member in iface.members:
if isinstance(member, xpidl.ConstMember) or isinstance(member, xpidl.CDATA):
continue
fd.write("/* %s */\n" % member.toIDL())
if isinstance(member, xpidl.Attribute):
--- a/xpcom/idl-parser/xpidl/xpidl.py
+++ b/xpcom/idl-parser/xpidl/xpidl.py
@@ -7,16 +7,17 @@
"""A parser for cross-platform IDL (XPIDL) files."""
import sys
import os.path
import re
from ply import lex
from ply import yacc
+from buildconfig import substs
"""A type conforms to the following pattern:
def isScriptable(self):
'returns True or False'
def nativeType(self, calltype):
'returns a string representation of the native type
@@ -711,16 +712,17 @@ class Attribute(object):
noscript = False
readonly = False
implicit_jscontext = False
nostdcall = False
must_use = False
binaryname = None
null = None
undefined = None
+ deleted = False
deprecated = False
infallible = False
def __init__(self, type, name, attlist, readonly, location, doccomments):
self.type = type
self.name = name
self.attlist = attlist
self.readonly = readonly
@@ -731,16 +733,24 @@ class Attribute(object):
if name == 'binaryname':
if value is None:
raise IDLError("binaryname attribute requires a value",
aloc)
self.binaryname = value
continue
+ if name == 'deleted':
+ if value is None:
+ raise IDLError("deleted attribute requires a value",
+ aloc)
+
+ self.deleted = substs['MOZ_WIDGET_TOOLKIT'] == value
+ continue
+
if name == 'Null':
if value is None:
raise IDLError("'Null' attribute requires a value", aloc)
if readonly:
raise IDLError("'Null' attribute only makes sense for setters",
aloc)
if value not in ('Empty', 'Null', 'Stringify'):
raise IDLError("'Null' attribute value must be 'Empty', 'Null' or 'Stringify'",
@@ -798,31 +808,32 @@ class Attribute(object):
def toIDL(self):
attribs = attlistToIDL(self.attlist)
readonly = self.readonly and 'readonly ' or ''
return "%s%sattribute %s %s;" % (attribs, readonly, self.type, self.name)
def isScriptable(self):
if not self.iface.attributes.scriptable:
return False
- return not self.noscript
+ return not (self.noscript or self.deleted)
def __str__(self):
return "\t%sattribute %s %s\n" % (self.readonly and 'readonly ' or '',
self.type, self.name)
def count(self):
return self.readonly and 1 or 2
class Method(object):
kind = 'method'
noscript = False
notxpcom = False
binaryname = None
+ deleted = False
implicit_jscontext = False
nostdcall = False
must_use = False
optional_argc = False
deprecated = False
def __init__(self, type, name, attlist, paramlist, location, doccomments, raises):
self.type = type
@@ -837,16 +848,24 @@ class Method(object):
if name == 'binaryname':
if value is None:
raise IDLError("binaryname attribute requires a value",
aloc)
self.binaryname = value
continue
+ if name == 'deleted':
+ if value is None:
+ raise IDLError("deleted attribute requires a value",
+ aloc)
+
+ self.deleted = substs['MOZ_WIDGET_TOOLKIT'] == value
+ continue
+
if value is not None:
raise IDLError("Unexpected attribute value", aloc)
if name == 'noscript':
self.noscript = True
elif name == 'notxpcom':
self.notxpcom = True
elif name == 'implicit_jscontext':
@@ -882,17 +901,17 @@ class Method(object):
if getBuiltinOrNativeTypeName(size_param.realtype) != 'unsigned long':
raise IDLError("is_size parameter must have type 'unsigned long'", self.location)
if not found_size_param:
raise IDLError("could not find is_size parameter '%s'" % p.size_is, self.location)
def isScriptable(self):
if not self.iface.attributes.scriptable:
return False
- return not (self.noscript or self.notxpcom)
+ return not (self.noscript or self.notxpcom or self.deleted)
def __str__(self):
return "\t%s %s(%s)\n" % (self.type, self.name, ", ".join([p.name for p in self.params]))
def toIDL(self):
if len(self.raises):
raises = ' raises (%s)' % ','.join(self.raises)
else:
--- a/xpcom/io/nsIFile.idl
+++ b/xpcom/io/nsIFile.idl
@@ -244,17 +244,22 @@ interface nsIFile : nsISupports
* path
* Find out what the nsIFile points at.
*
* Note that the ACString attributes are returned in the
* native filesystem charset.
*
*/
readonly attribute AString target;
- [noscript] readonly attribute ACString nativeTarget;
+ /**
+ * We only provide this API for Unix-like platforms, because
+ * it would be lossy on Windows.
+ */
+ [noscript, deleted(windows)]
+ readonly attribute ACString nativeTarget;
readonly attribute AString path;
[noscript] readonly attribute ACString nativePath;
boolean exists();
boolean isWritable();
boolean isReadable();
boolean isExecutable();
boolean isHidden();
--- a/xpcom/io/nsLocalFileWin.cpp
+++ b/xpcom/io/nsLocalFileWin.cpp
@@ -3630,32 +3630,16 @@ nsLocalFile::MoveToNative(nsIFile* aNewP
nsresult rv = NS_CopyNativeToUnicode(aNewName, tmp);
if (NS_SUCCEEDED(rv)) {
return MoveTo(aNewParentDir, tmp);
}
return rv;
}
-NS_IMETHODIMP
-nsLocalFile::GetNativeTarget(nsACString& aResult)
-{
- // Check we are correctly initialized.
- CHECK_mWorkingPath();
-
- NS_WARNING("This API is lossy. Use GetTarget !");
- nsAutoString tmp;
- nsresult rv = GetTarget(tmp);
- if (NS_SUCCEEDED(rv)) {
- rv = NS_CopyUnicodeToNative(tmp, aResult);
- }
-
- return rv;
-}
-
nsresult
NS_NewNativeLocalFile(const nsACString& aPath, bool aFollowLinks,
nsIFile** aResult)
{
nsAutoString buf;
nsresult rv = NS_CopyNativeToUnicode(aPath, buf);
if (NS_FAILED(rv)) {
*aResult = nullptr;