]> granicus.if.org Git - clang/commitdiff
Validate Microsoft's uuid attribute string.
authorFrancois Pichet <pichet2000@gmail.com>
Mon, 20 Dec 2010 01:41:49 +0000 (01:41 +0000)
committerFrancois Pichet <pichet2000@gmail.com>
Mon, 20 Dec 2010 01:41:49 +0000 (01:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122220 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/Parser/MicrosoftExtensions.c

index cfa2ab6d2103be6c50ebd29c91ce8302dfa520a1..b616cd9a3c0c1eb8c065e2f8c97ced7fcdd2c04c 100644 (file)
@@ -929,6 +929,8 @@ def err_attribute_argument_out_of_bounds : Error<
   "'%0' attribute parameter %1 is out of bounds">;
 def err_attribute_requires_objc_interface : Error<
   "attribute may only be applied to an Objective-C interface">;
+def err_attribute_uuid_malformed_guid : Error<
+  "uuid attribute contains a malformed GUID">;
 def warn_nonnull_pointers_only : Warning<
   "nonnull attribute only applies to pointer arguments">;
 def err_attribute_invalid_implicit_this_argument : Error<
index b0e022fd335c382b0827da988549b6eb8e296354..e77a660ada10fbb61ee013392efa702e601cecad 100644 (file)
@@ -2533,12 +2533,50 @@ static void HandleUuidAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     }
     Expr *Arg = Attr.getArg(0);
     StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
+    if (Str == 0 || Str->isWide()) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
+        << "uuid" << 1;
+      return;
+    }
+
+    llvm::StringRef StrRef = Str->getString();
+
+    bool IsCurly = StrRef.size() > 1 && StrRef.front() == '{' &&
+                   StrRef.back() == '}';
+    
+    // Validate GUID length.
+    if (IsCurly && StrRef.size() != 38) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
+      return;
+    }
+    if (!IsCurly && StrRef.size() != 36) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
+      return;
+    }
+
+    // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or 
+    // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
+    llvm::StringRef::iterator I = StrRef.begin();\r
+    if (IsCurly) // Skip the optional '{'\r
+       ++I;\r
+\r
+    for (int i = 0; i < 36; ++i) {\r
+      if (i == 8 || i == 13 || i == 18 || i == 23) {
+        if (*I != '-') {
+          S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
+          return;
+        }
+      } else if (!isxdigit(*I)) {
+        S.Diag(Attr.getLoc(), diag::err_attribute_uuid_malformed_guid);
+        return;
+      }
+      I++;
+    }
 
     d->addAttr(::new (S.Context) UuidAttr(Attr.getLoc(), S.Context, 
                                           Str->getString()));
-  } else {
+  } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
-  }
 }
 
 //===----------------------------------------------------------------------===//
index 6c14742278e29177764c143e18c46c732ccc39fb..98c86253f768d5fef1ffe1e12e66d182072d9869 100644 (file)
@@ -55,8 +55,16 @@ typedef struct _GUID
     unsigned short Data3;
     unsigned char  Data4[8];
 } GUID;
+
+struct __declspec(uuid(L"00000000-0000-0000-1234-000000000047")) uuid_attr_bad1 { };// expected-error {{'uuid' attribute requires parameter 1 to be a string}}
+struct __declspec(uuid(3)) uuid_attr_bad2 { };// expected-error {{'uuid' attribute requires parameter 1 to be a string}}
+struct __declspec(uuid("0000000-0000-0000-1234-0000500000047")) uuid_attr_bad3 { };// expected-error {{uuid attribute contains a malformed GUID}}
+struct __declspec(uuid("0000000-0000-0000-Z234-000000000047")) uuid_attr_bad4 { };// expected-error {{uuid attribute contains a malformed GUID}}
+struct __declspec(uuid("000000000000-0000-1234-000000000047")) uuid_attr_bad5 { };// expected-error {{uuid attribute contains a malformed GUID}}
+
+
 struct __declspec(uuid("00000000-0000-0000-3231-000000000046")) A { };
-struct __declspec(uuid("00000000-0000-0000-1234-000000000047")) B { };
+struct __declspec(uuid("{00000000-0000-0000-1234-000000000047}")) B { };
 class C {};
 
 void uuidof_test2()