]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: policy can parse IfExists conditions
authorCasey Bodley <cbodley@redhat.com>
Thu, 20 Jul 2017 20:06:27 +0000 (16:06 -0400)
committerCasey Bodley <cbodley@redhat.com>
Fri, 21 Jul 2017 15:41:26 +0000 (11:41 -0400)
when ParseState::key() encounters a condition statement ending with
IfExists, it looks up the token by its prefix only

because this prefix is not null-terminated, the gperf-generated
comparison has to be modified to use strncmp() instead of strcmp() by
adding the %compare-strncmp flag to the gperf file

Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/rgw_iam_policy.cc
src/rgw/rgw_iam_policy.h
src/rgw/rgw_iam_policy_keywords.gperf

index 22a4bbbf542dcad0ed58eafa33c8113abeff64c5..f90bfac788310e1d45dacd96aa7bf73be0320c1a 100644 (file)
@@ -473,6 +473,7 @@ struct ParseState {
 
   bool arraying = false;
   bool objecting = false;
+  bool cond_ifexists = false;
 
   void reset();
 
@@ -645,13 +646,22 @@ bool ParseState::obj_end() {
 }
 
 bool ParseState::key(const char* s, size_t l) {
-  auto k = pp->tokens.lookup(s, l);
+  auto token_len = l;
+  bool ifexists = false;
+  if (w->id == TokenID::Condition && w->kind == TokenKind::statement) {
+    static constexpr char IfExists[] = "IfExists";
+    if (boost::algorithm::ends_with(boost::string_view{s, l}, IfExists)) {
+      ifexists = true;
+      token_len -= sizeof(IfExists)-1;
+    }
+  }
+  auto k = pp->tokens.lookup(s, token_len);
 
   if (!k) {
     if (w->kind == TokenKind::cond_op) {
       auto& t = pp->policy.statements.back();
       pp->s.emplace_back(pp, cond_key);
-      t.conditions.emplace_back(w->id, s, l);
+      t.conditions.emplace_back(w->id, s, l, cond_ifexists);
       return true;
     } else {
       return false;
@@ -680,6 +690,7 @@ bool ParseState::key(const char* s, size_t l) {
   } else if ((w->id == TokenID::Condition) &&
             (k->kind == TokenKind::cond_op)) {
     pp->s.emplace_back(pp, k);
+    pp->s.back().cond_ifexists = ifexists;
     return true;
   }
   return false;
index 674d7be08894f64809832b4129d57eb275d2a5f9..55f420f0ae70c891a0abdb6bcfcf6bcfa26d79d8 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "fnmatch.h"
 
+#include "rgw_acl.h"
 #include "rgw_basic_types.h"
 #include "rgw_iam_policy_keywords.h"
 
@@ -273,18 +274,8 @@ struct Condition {
   std::vector<std::string> vals;
 
   Condition() = default;
-  Condition(TokenID op, const char* s, std::size_t len) : op(op) {
-    static constexpr char ifexistr[] = "IfExists";
-    auto l = static_cast<const char*>(memmem(static_cast<const void*>(s), len,
-                                            static_cast<const void*>(ifexistr),
-                                            sizeof(ifexistr) -1));
-    if (l && ((l + sizeof(ifexistr) - 1 == (s + len)))) {
-      ifexists = true;
-      key.assign(s, static_cast<const char*>(l) - s);
-    } else {
-      key.assign(s, len);
-    }
-  }
+  Condition(TokenID op, const char* s, std::size_t len, bool ifexists)
+    : op(op), key(s, len), ifexists(ifexists) {}
 
   bool eval(const Environment& e) const;
 
index d37fa6aff65398edcb4d987eef9102e85482fd5a..57a732c02fb37c184c8997239e9cb0a3eb35d4ff 100644 (file)
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 %language=C++
+%compare-strncmp
 %define class-name keyword_hash
 %define lookup-function-name lookup
 %struct-type