1/* 2 * Copyright (C) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 17#include "appspawn_utils.h" 18#include "command_lexer.h" 19 20using namespace OHOS::AppSpawn; 21 22enum class ParsingState { 23 INIT, 24 IN_WHITESPACE, 25 IN_ARGUMENT, 26 IN_SINGLE_QUOTE, 27 IN_DOUBLE_QUOTE, 28}; 29 30bool CommandLexer::GetAllArguments(std::vector<std::string> &args) 31{ 32 constexpr char singleQuote = '\''; 33 constexpr char doubleQuote = '"'; 34 ParsingState state = ParsingState::INIT; 35 std::string lastArg; 36 37 for (size_t i = 0; i < str_.size(); i++) { 38 switch (state) { 39 case ParsingState::INIT: 40 if (isspace(str_[i])) { 41 state = ParsingState::IN_WHITESPACE; 42 } else if (str_[i] == singleQuote) { 43 state = ParsingState::IN_SINGLE_QUOTE; 44 } else if (str_[i] == doubleQuote) { 45 state = ParsingState::IN_DOUBLE_QUOTE; 46 } else { 47 state = ParsingState::IN_ARGUMENT; 48 lastArg += str_[i]; 49 } 50 break; 51 case ParsingState::IN_WHITESPACE: 52 if (str_[i] == singleQuote) { 53 state = ParsingState::IN_SINGLE_QUOTE; 54 } else if (str_[i] == doubleQuote) { 55 state = ParsingState::IN_DOUBLE_QUOTE; 56 } else if (!isspace(str_[i])) { 57 state = ParsingState::IN_ARGUMENT; 58 lastArg += str_[i]; 59 } 60 break; 61 case ParsingState::IN_ARGUMENT: 62 if (isspace(str_[i])) { 63 args.push_back(std::move(lastArg)); 64 // Whether a moved string is empty depends on the 65 // implementation of C++ std library, so clear() is called. 66 lastArg.clear(); 67 state = ParsingState::IN_WHITESPACE; 68 } else if (str_[i] == singleQuote) { 69 state = ParsingState::IN_SINGLE_QUOTE; 70 } else if (str_[i] == doubleQuote) { 71 state = ParsingState::IN_DOUBLE_QUOTE; 72 } else { 73 lastArg += str_[i]; 74 } 75 break; 76 case ParsingState::IN_SINGLE_QUOTE: 77 if (str_[i] == singleQuote) { 78 state = ParsingState::IN_ARGUMENT; 79 } else { 80 lastArg += str_[i]; 81 } 82 break; 83 case ParsingState::IN_DOUBLE_QUOTE: 84 if (str_[i] == doubleQuote) { 85 state = ParsingState::IN_ARGUMENT; 86 } else { 87 lastArg += str_[i]; 88 } 89 break; 90 } 91 } 92 93 if (state == ParsingState::IN_ARGUMENT) { 94 args.push_back(std::move(lastArg)); 95 } else if (state == ParsingState::IN_SINGLE_QUOTE || 96 state == ParsingState::IN_DOUBLE_QUOTE) { 97 APPSPAWN_LOGE("Parsing arguments failed: missing terminated quote"); 98 args.clear(); 99 return false; 100 } 101 102 return true; 103} 104