1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "src/traced/probes/ftrace/ftrace_config_utils.h" 18 19 #include "perfetto/base/logging.h" 20 21 namespace perfetto { 22 namespace { 23 24 // Excludes \r, \n, escape sequences and control chars. IsPrintableASCIIOrSpace(char c)25bool IsPrintableASCIIOrSpace(char c) { 26 return c >= 32 && c < 127; 27 } 28 IsValidAtraceEventName(const std::string & str)29bool IsValidAtraceEventName(const std::string& str) { 30 for (size_t i = 0; i < str.size(); i++) { 31 if (!IsPrintableASCIIOrSpace(str[i])) 32 return false; 33 } 34 return true; 35 } 36 IsValidFtraceEventName(const std::string & str)37bool IsValidFtraceEventName(const std::string& str) { 38 int slash_count = 0; 39 for (size_t i = 0; i < str.size(); i++) { 40 if (!IsPrintableASCIIOrSpace(str[i])) 41 return false; 42 if (str[i] == '/') { 43 slash_count++; 44 // At most one '/' allowed and not at the beginning or end. 45 if (slash_count > 1 || i == 0 || i == str.size() - 1) 46 return false; 47 } 48 if (str[i] == '*' && i != str.size() - 1) 49 return false; 50 } 51 return true; 52 } 53 54 } // namespace 55 CreateFtraceConfig(std::set<std::string> names)56FtraceConfig CreateFtraceConfig(std::set<std::string> names) { 57 FtraceConfig config; 58 for (const std::string& name : names) 59 *config.add_ftrace_events() = name; 60 return config; 61 } 62 RequiresAtrace(const FtraceConfig & config)63bool RequiresAtrace(const FtraceConfig& config) { 64 return !config.atrace_categories().empty() || !config.atrace_apps().empty(); 65 } 66 ValidConfig(const FtraceConfig & config)67bool ValidConfig(const FtraceConfig& config) { 68 for (const std::string& event_name : config.ftrace_events()) { 69 if (!IsValidFtraceEventName(event_name)) { 70 PERFETTO_ELOG("Bad event name '%s'", event_name.c_str()); 71 return false; 72 } 73 } 74 for (const std::string& category : config.atrace_categories()) { 75 if (!IsValidAtraceEventName(category)) { 76 PERFETTO_ELOG("Bad category name '%s'", category.c_str()); 77 return false; 78 } 79 } 80 for (const std::string& app : config.atrace_apps()) { 81 if (!IsValidAtraceEventName(app)) { 82 PERFETTO_ELOG("Bad app '%s'", app.c_str()); 83 return false; 84 } 85 } 86 return true; 87 } 88 89 } // namespace perfetto 90