Commit 7e767178 authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by Kevin Modzelewski

Enable validation of printf-style format strings

And fix some of the issues that this found.
parent 3307cddc
......@@ -764,7 +764,8 @@ void addToSysArgv(const char* str);
// The traceback given to the user will include this,
// even though the execution didn't actually arrive there.
void raiseSyntaxError(const char* msg, int lineno, int col_offset, llvm::StringRef file, llvm::StringRef func);
void raiseSyntaxErrorHelper(llvm::StringRef file, llvm::StringRef func, AST* node_at, const char* msg, ...);
void raiseSyntaxErrorHelper(llvm::StringRef file, llvm::StringRef func, AST* node_at, const char* msg, ...)
__attribute__((format(printf, 4, 5)));
struct LineInfo {
public:
......
......@@ -604,14 +604,14 @@ void dictMergeFromSeq2(BoxedDict* self, Box* other) {
if (element->cls == list_cls) {
BoxedList* list = static_cast<BoxedList*>(element);
if (list->size != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %ld; 2 is required", idx,
list->size);
self->d[list->elts->elts[0]] = list->elts->elts[1];
} else if (element->cls == tuple_cls) {
BoxedTuple* tuple = static_cast<BoxedTuple*>(element);
if (tuple->size() != 2)
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %d; 2 is required", idx,
raiseExcHelper(ValueError, "dictionary update sequence element #%d has length %ld; 2 is required", idx,
tuple->size());
self->d[tuple->elts[0]] = tuple->elts[1];
......
......@@ -1222,7 +1222,8 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedS
Box* rtn = *reinterpret_cast<Box**>((char*)obj + member_desc->offset);
if (rtn == NULL) {
raiseExcHelper(AttributeError, "%.*s", attr_name->size(), attr_name->data());
assert(attr_name->data()[attr_name->size()] == '\0');
raiseExcHelper(AttributeError, "%s", attr_name->data());
}
return rtn;
}
......@@ -1356,8 +1357,9 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedS
// is of that type.
if (getset_descr->get == NULL) {
raiseExcHelper(AttributeError, "attribute '%.*s' of '%s' object is not readable", attr_name->size(),
attr_name->data(), getTypeName(getset_descr));
assert(attr_name->data()[attr_name->size()] == '\0');
raiseExcHelper(AttributeError, "attribute '%s' of '%s' object is not readable", attr_name->data(),
getTypeName(getset_descr));
}
// Abort because right now we can't call twice in a rewrite
......@@ -2041,8 +2043,9 @@ bool dataDescriptorSetSpecialCases(Box* obj, Box* val, Box* descr, SetattrRewrit
// TODO type checking goes here
if (getset_descr->set == NULL) {
raiseExcHelper(AttributeError, "attribute '%.*s' of '%s' objects is not writable", attr_name->size(),
attr_name->data(), getTypeName(obj));
assert(attr_name->data()[attr_name->size()] == '\0');
raiseExcHelper(AttributeError, "attribute '%s' of '%s' objects is not writable", attr_name->data(),
getTypeName(obj));
}
if (rewrite_args) {
......@@ -3235,7 +3238,7 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
Box* ovarargs = BoxedTuple::create(unused_positional.size(), &unused_positional[0]);
getArg(varargs_idx, oarg1, oarg2, oarg3, oargs) = ovarargs;
} else if (unused_positional.size()) {
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%d given)", func_name, paramspec.num_args,
raiseExcHelper(TypeError, "%s() takes at most %d argument%s (%ld given)", func_name, paramspec.num_args,
(paramspec.num_args == 1 ? "" : "s"), argspec.num_args + argspec.num_keywords + varargs.size());
}
......@@ -3335,7 +3338,7 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
for (int i = 0; i < paramspec.num_args - paramspec.num_defaults; i++) {
if (params_filled[i])
continue;
raiseExcHelper(TypeError, "%s() takes exactly %d arguments (%d given)", func_name, paramspec.num_args,
raiseExcHelper(TypeError, "%s() takes exactly %d arguments (%ld given)", func_name, paramspec.num_args,
argspec.num_args + argspec.num_keywords + varargs.size());
}
......@@ -4902,8 +4905,8 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs*
} else {
// the exception cpthon throws is different when the class contains the attribute
if (clsAttr != NULL) {
raiseExcHelper(AttributeError, "'%s' object attribute '%.*s' is read-only", getTypeName(obj), attr->size(),
attr->data());
assert(attr->data()[attr->size()] == '\0');
raiseExcHelper(AttributeError, "'%s' object attribute '%s' is read-only", getTypeName(obj), attr->data());
} else {
assert(attr->data()[attr->size()] == '\0');
raiseAttributeError(obj, attr->s());
......
......@@ -46,7 +46,8 @@ void default_free(void*);
void dealloc_null(Box* box);
// helper function for raising from the runtime:
void raiseExcHelper(BoxedClass*, const char* fmt, ...) __attribute__((__noreturn__));
void raiseExcHelper(BoxedClass*, const char* fmt, ...) __attribute__((__noreturn__))
__attribute__((format(printf, 2, 3)));
void raiseExcHelper(BoxedClass*, Box* arg) __attribute__((__noreturn__));
BoxedModule* getCurrentModule();
......
......@@ -1185,7 +1185,7 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
PyErr_SetString(TypeError, objectNewParameterTypeErrorMsg());
return NULL;
} else
raiseExcHelper(TypeError, objectNewParameterTypeErrorMsg());
raiseExcHelper(TypeError, "%s", objectNewParameterTypeErrorMsg());
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment