/* * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "appspawn_utils.h" #include "command_lexer.h" using namespace OHOS::AppSpawn; enum class ParsingState { INIT, IN_WHITESPACE, IN_ARGUMENT, IN_SINGLE_QUOTE, IN_DOUBLE_QUOTE, }; bool CommandLexer::GetAllArguments(std::vector &args) { constexpr char singleQuote = '\''; constexpr char doubleQuote = '"'; ParsingState state = ParsingState::INIT; std::string lastArg; for (size_t i = 0; i < str_.size(); i++) { switch (state) { case ParsingState::INIT: if (isspace(str_[i])) { state = ParsingState::IN_WHITESPACE; } else if (str_[i] == singleQuote) { state = ParsingState::IN_SINGLE_QUOTE; } else if (str_[i] == doubleQuote) { state = ParsingState::IN_DOUBLE_QUOTE; } else { state = ParsingState::IN_ARGUMENT; lastArg += str_[i]; } break; case ParsingState::IN_WHITESPACE: if (str_[i] == singleQuote) { state = ParsingState::IN_SINGLE_QUOTE; } else if (str_[i] == doubleQuote) { state = ParsingState::IN_DOUBLE_QUOTE; } else if (!isspace(str_[i])) { state = ParsingState::IN_ARGUMENT; lastArg += str_[i]; } break; case ParsingState::IN_ARGUMENT: if (isspace(str_[i])) { args.push_back(std::move(lastArg)); // Whether a moved string is empty depends on the // implementation of C++ std library, so clear() is called. lastArg.clear(); state = ParsingState::IN_WHITESPACE; } else if (str_[i] == singleQuote) { state = ParsingState::IN_SINGLE_QUOTE; } else if (str_[i] == doubleQuote) { state = ParsingState::IN_DOUBLE_QUOTE; } else { lastArg += str_[i]; } break; case ParsingState::IN_SINGLE_QUOTE: if (str_[i] == singleQuote) { state = ParsingState::IN_ARGUMENT; } else { lastArg += str_[i]; } break; case ParsingState::IN_DOUBLE_QUOTE: if (str_[i] == doubleQuote) { state = ParsingState::IN_ARGUMENT; } else { lastArg += str_[i]; } break; } } if (state == ParsingState::IN_ARGUMENT) { args.push_back(std::move(lastArg)); } else if (state == ParsingState::IN_SINGLE_QUOTE || state == ParsingState::IN_DOUBLE_QUOTE) { APPSPAWN_LOGE("Parsing arguments failed: missing terminated quote"); args.clear(); return false; } return true; }