<commit_before>// Copyright 2017 Google LLC
//
// 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 "riegeli/messages/message_parse.h"

#include <stddef.h>
#include <stdint.h>

#include <limits>
#include <string>

#include "absl/base/attributes.h"
#include "absl/base/optimization.h"
#include "absl/status/status.h"
#include "absl/strings/cord.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "google/protobuf/message_lite.h"
#include "riegeli/base/base.h"
#include "riegeli/base/chain.h"
#include "riegeli/bytes/chain_reader.h"
#include "riegeli/bytes/cord_reader.h"
#include "riegeli/bytes/limiting_reader.h"
#include "riegeli/bytes/reader.h"

namespace riegeli {

namespace {

ABSL_ATTRIBUTE_COLD
inline absl::Status ParseError(google::protobuf::MessageLite& dest) {
  return absl::InvalidArgumentError(
      absl::StrCat("Failed to parse message of type ", dest.GetTypeName()));
}

ABSL_ATTRIBUTE_COLD
inline absl::Status ParseError(Reader& src,
                               google::protobuf::MessageLite& dest) {
  return src.AnnotateStatus(ParseError(dest));
}

inline absl::Status CheckInitialized(google::protobuf::MessageLite& dest,
                                     ParseOptions options) {
  if (!options.partial() && ABSL_PREDICT_FALSE(!dest.IsInitialized())) {
    return absl::InvalidArgumentError(
        absl::StrCat("Failed to parse message of type ", dest.GetTypeName(),
                     " because it is missing required fields: ",
                     dest.InitializationErrorString()));
  }
  return absl::OkStatus();
}

inline absl::Status CheckInitialized(Reader& src,
                                     google::protobuf::MessageLite& dest,
                                     ParseOptions options) {
  if (!options.partial() && ABSL_PREDICT_FALSE(!dest.IsInitialized())) {
    return src.AnnotateStatus(absl::InvalidArgumentError(
        absl::StrCat("Failed to parse message of type ", dest.GetTypeName(),
                     " because it is missing required fields: ",
                     dest.InitializationErrorString())));
  }
  return absl::OkStatus();
}

}  // namespace

namespace messages_internal {

absl::Status ParseFromReaderImpl(Reader& src,
                                 google::protobuf::MessageLite& dest,
                                 ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      src.SupportsSize()) {
    const absl::optional<Position> size = src.Size();
    if (ABSL_PREDICT_FALSE(size == absl::nullopt)) return src.status();
    src.Pull();
    if (src.limit_pos() == *size && src.available() <= kMaxBytesToCopy) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      const bool parse_ok = dest.ParsePartialFromArray(
          src.cursor(), IntCast<int>(src.available()));
      src.move_cursor(src.available());
      if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(src, dest);
      return CheckInitialized(src, dest, options);
    }
  }
  ReaderInputStream input_stream(&src);
  if (!options.merge()) dest.Clear();
  bool parse_ok;
  if (options.recursion_limit() ==
      google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.MergePartialFromBoundedZeroCopyStream(&input_stream, -1);
  } else {
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  if (ABSL_PREDICT_FALSE(!src.ok())) return src.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(src, dest);
  return CheckInitialized(src, dest, options);
}

}  // namespace messages_internal

absl::Status ParseFromReaderWithLength(Reader& src, size_t length,
                                       google::protobuf::MessageLite& dest,
                                       ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      length <= kMaxBytesToCopy) {
    src.Pull();
    if (src.available() >= length) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      const bool parse_ok =
          dest.ParsePartialFromArray(src.cursor(), IntCast<int>(length));
      src.move_cursor(length);
      if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(src, dest);
      return CheckInitialized(src, dest, options);
    }
  }
  LimitingReader<> reader(
      &src, LimitingReaderBase::Options().set_exact_length(length));
  ReaderInputStream input_stream(&reader);
  if (!options.merge()) dest.Clear();
  bool parse_ok;
  if (options.recursion_limit() ==
      google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.MergePartialFromBoundedZeroCopyStream(&input_stream, -1);
  } else {
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  if (ABSL_PREDICT_FALSE(!reader.ok())) return reader.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(reader, dest);
  const absl::Status status = CheckInitialized(reader, dest, options);
  if (!reader.Close()) {
    RIEGELI_ASSERT_UNREACHABLE() << "A LimitingReader with !fail_if_longer() "
                                    "has no reason to fail only in Close(): "
                                 << reader.status();
  }
  return status;
}

absl::Status ParseFromString(absl::string_view src,
                             google::protobuf::MessageLite& dest,
                             ParseOptions options) {
  bool parse_ok;
  if (ABSL_PREDICT_FALSE(src.size() >
                         size_t{std::numeric_limits<int>::max()})) {
    parse_ok = false;
  } else if (!options.merge() && options.recursion_limit() ==
                                     google::protobuf::io::CodedInputStream::
                                         GetDefaultRecursionLimit()) {
    parse_ok = dest.ParsePartialFromArray(src.data(), IntCast<int>(src.size()));
  } else {
    if (!options.merge()) dest.Clear();
    google::protobuf::io::ArrayInputStream input_stream(
        src.data(), IntCast<int>(src.size()));
    if (options.recursion_limit() ==
        google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
      parse_ok = dest.MergePartialFromBoundedZeroCopyStream(&input_stream, -1);
    } else {
      google::protobuf::io::CodedInputStream coded_stream(&input_stream);
      coded_stream.SetRecursionLimit(options.recursion_limit());
      parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
                 coded_stream.ConsumedEntireMessage();
    }
  }
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(dest);
  return CheckInitialized(dest, options);
}

absl::Status ParseFromChain(const Chain& src,
                            google::protobuf::MessageLite& dest,
                            ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      src.size() <= kMaxBytesToCopy) {
    if (const absl::optional<absl::string_view> flat = src.TryFlat()) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      if (ABSL_PREDICT_FALSE(!dest.ParsePartialFromArray(
              flat->data(), IntCast<int>(flat->size())))) {
        return ParseError(dest);
      }
      return CheckInitialized(dest, options);
    }
  }
  ChainReader<> reader(&src);
  ReaderInputStream input_stream(&reader);
  if (!options.merge()) dest.Clear();
  bool parse_ok;
  if (options.recursion_limit() ==
      google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.MergePartialFromBoundedZeroCopyStream(&input_stream, -1);
  } else {
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  RIEGELI_ASSERT(reader.ok())
      << "A ChainReader has no reason to fail: " << reader.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(dest);
  return CheckInitialized(dest, options);
}

absl::Status ParseFromCord(const absl::Cord& src,
                           google::protobuf::MessageLite& dest,
                           ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      src.size() <= kMaxBytesToCopy) {
    if (const absl::optional<absl::string_view> flat = src.TryFlat()) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      if (ABSL_PREDICT_FALSE(!dest.ParsePartialFromArray(
              flat->data(), IntCast<int>(flat->size())))) {
        return ParseError(dest);
      }
      return CheckInitialized(dest, options);
    }
  }
  CordReader<> reader(&src);
  ReaderInputStream input_stream(&reader);
  if (!options.merge()) dest.Clear();
  bool parse_ok;
  if (options.recursion_limit() ==
      google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.MergePartialFromBoundedZeroCopyStream(&input_stream, -1);
  } else {
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  RIEGELI_ASSERT(reader.ok())
      << "A CordReader has no reason to fail: " << reader.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(dest);
  return CheckInitialized(dest, options);
}

bool ReaderInputStream::Next(const void** data, int* size) {
  if (ABSL_PREDICT_FALSE(src_->pos() >=
                         Position{std::numeric_limits<int64_t>::max()})) {
    return false;
  }
  const Position max_length =
      Position{std::numeric_limits<int64_t>::max()} - src_->pos();
  if (ABSL_PREDICT_FALSE(!src_->Pull())) return false;
  *data = src_->cursor();
  *size = SaturatingIntCast<int>(UnsignedMin(src_->available(), max_length));
  src_->move_cursor(IntCast<size_t>(*size));
  return true;
}

void ReaderInputStream::BackUp(int length) {
  RIEGELI_ASSERT_GE(length, 0)
      << "Failed precondition of ZeroCopyInputStream::BackUp(): "
         "negative length";
  RIEGELI_ASSERT_LE(IntCast<size_t>(length), src_->start_to_cursor())
      << "Failed precondition of ZeroCopyInputStream::BackUp(): "
         "length larger than the amount of buffered data";
  src_->set_cursor(src_->cursor() - length);
}

bool ReaderInputStream::Skip(int length) {
  RIEGELI_ASSERT_GE(length, 0)
      << "Failed precondition of ZeroCopyInputStream::Skip(): negative length";
  const Position max_length =
      SaturatingSub(Position{std::numeric_limits<int64_t>::max()}, src_->pos());
  const size_t length_to_skip =
      UnsignedMin(IntCast<size_t>(length), max_length);
  return src_->Skip(length_to_skip) &&
         length_to_skip == IntCast<size_t>(length);
}

int64_t ReaderInputStream::ByteCount() const {
  return SaturatingIntCast<int64_t>(src_->pos());
}

}  // namespace riegeli
<commit_msg>Fix proto parsing.<commit_after>// Copyright 2017 Google LLC
//
// 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 "riegeli/messages/message_parse.h"

#include <stddef.h>
#include <stdint.h>

#include <limits>
#include <string>

#include "absl/base/attributes.h"
#include "absl/base/optimization.h"
#include "absl/status/status.h"
#include "absl/strings/cord.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include "google/protobuf/message_lite.h"
#include "riegeli/base/base.h"
#include "riegeli/base/chain.h"
#include "riegeli/bytes/chain_reader.h"
#include "riegeli/bytes/cord_reader.h"
#include "riegeli/bytes/limiting_reader.h"
#include "riegeli/bytes/reader.h"

namespace riegeli {

namespace {

ABSL_ATTRIBUTE_COLD
inline absl::Status ParseError(google::protobuf::MessageLite& dest) {
  return absl::InvalidArgumentError(
      absl::StrCat("Failed to parse message of type ", dest.GetTypeName()));
}

ABSL_ATTRIBUTE_COLD
inline absl::Status ParseError(Reader& src,
                               google::protobuf::MessageLite& dest) {
  return src.AnnotateStatus(ParseError(dest));
}

inline absl::Status CheckInitialized(google::protobuf::MessageLite& dest,
                                     ParseOptions options) {
  if (!options.partial() && ABSL_PREDICT_FALSE(!dest.IsInitialized())) {
    return absl::InvalidArgumentError(
        absl::StrCat("Failed to parse message of type ", dest.GetTypeName(),
                     " because it is missing required fields: ",
                     dest.InitializationErrorString()));
  }
  return absl::OkStatus();
}

inline absl::Status CheckInitialized(Reader& src,
                                     google::protobuf::MessageLite& dest,
                                     ParseOptions options) {
  if (!options.partial() && ABSL_PREDICT_FALSE(!dest.IsInitialized())) {
    return src.AnnotateStatus(absl::InvalidArgumentError(
        absl::StrCat("Failed to parse message of type ", dest.GetTypeName(),
                     " because it is missing required fields: ",
                     dest.InitializationErrorString())));
  }
  return absl::OkStatus();
}

}  // namespace

namespace messages_internal {

absl::Status ParseFromReaderImpl(Reader& src,
                                 google::protobuf::MessageLite& dest,
                                 ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      src.SupportsSize()) {
    const absl::optional<Position> size = src.Size();
    if (ABSL_PREDICT_FALSE(size == absl::nullopt)) return src.status();
    src.Pull();
    if (src.limit_pos() == *size && src.available() <= kMaxBytesToCopy) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      const bool parse_ok = dest.ParsePartialFromArray(
          src.cursor(), IntCast<int>(src.available()));
      src.move_cursor(src.available());
      if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(src, dest);
      return CheckInitialized(src, dest, options);
    }
  }
  ReaderInputStream input_stream(&src);
  bool parse_ok;
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.ParsePartialFromZeroCopyStream(&input_stream);
  } else {
    if (!options.merge()) dest.Clear();
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  if (ABSL_PREDICT_FALSE(!src.ok())) return src.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(src, dest);
  return CheckInitialized(src, dest, options);
}

}  // namespace messages_internal

absl::Status ParseFromReaderWithLength(Reader& src, size_t length,
                                       google::protobuf::MessageLite& dest,
                                       ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      length <= kMaxBytesToCopy) {
    src.Pull();
    if (src.available() >= length) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      const bool parse_ok =
          dest.ParsePartialFromArray(src.cursor(), IntCast<int>(length));
      src.move_cursor(length);
      if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(src, dest);
      return CheckInitialized(src, dest, options);
    }
  }
  LimitingReader<> reader(
      &src, LimitingReaderBase::Options().set_exact_length(length));
  ReaderInputStream input_stream(&reader);
  bool parse_ok;
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.ParsePartialFromZeroCopyStream(&input_stream);
  } else {
    if (!options.merge()) dest.Clear();
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  if (ABSL_PREDICT_FALSE(!reader.ok())) return reader.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(reader, dest);
  const absl::Status status = CheckInitialized(reader, dest, options);
  if (!reader.Close()) {
    RIEGELI_ASSERT_UNREACHABLE() << "A LimitingReader with !fail_if_longer() "
                                    "has no reason to fail only in Close(): "
                                 << reader.status();
  }
  return status;
}

absl::Status ParseFromString(absl::string_view src,
                             google::protobuf::MessageLite& dest,
                             ParseOptions options) {
  bool parse_ok;
  if (ABSL_PREDICT_FALSE(src.size() >
                         size_t{std::numeric_limits<int>::max()})) {
    parse_ok = false;
  } else if (!options.merge() && options.recursion_limit() ==
                                     google::protobuf::io::CodedInputStream::
                                         GetDefaultRecursionLimit()) {
    parse_ok = dest.ParsePartialFromArray(src.data(), IntCast<int>(src.size()));
  } else {
    if (!options.merge()) dest.Clear();
    google::protobuf::io::ArrayInputStream input_stream(
        src.data(), IntCast<int>(src.size()));
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(dest);
  return CheckInitialized(dest, options);
}

absl::Status ParseFromChain(const Chain& src,
                            google::protobuf::MessageLite& dest,
                            ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      src.size() <= kMaxBytesToCopy) {
    if (const absl::optional<absl::string_view> flat = src.TryFlat()) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      if (ABSL_PREDICT_FALSE(!dest.ParsePartialFromArray(
              flat->data(), IntCast<int>(flat->size())))) {
        return ParseError(dest);
      }
      return CheckInitialized(dest, options);
    }
  }
  ChainReader<> reader(&src);
  ReaderInputStream input_stream(&reader);
  bool parse_ok;
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.ParsePartialFromZeroCopyStream(&input_stream);
  } else {
    if (!options.merge()) dest.Clear();
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  RIEGELI_ASSERT(reader.ok())
      << "A ChainReader has no reason to fail: " << reader.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(dest);
  return CheckInitialized(dest, options);
}

absl::Status ParseFromCord(const absl::Cord& src,
                           google::protobuf::MessageLite& dest,
                           ParseOptions options) {
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit() &&
      src.size() <= kMaxBytesToCopy) {
    if (const absl::optional<absl::string_view> flat = src.TryFlat()) {
      // The data are flat. `ParsePartialFromArray()` is faster than
      // `ParsePartialFromZeroCopyStream()`.
      if (ABSL_PREDICT_FALSE(!dest.ParsePartialFromArray(
              flat->data(), IntCast<int>(flat->size())))) {
        return ParseError(dest);
      }
      return CheckInitialized(dest, options);
    }
  }
  CordReader<> reader(&src);
  ReaderInputStream input_stream(&reader);
  bool parse_ok;
  if (!options.merge() &&
      options.recursion_limit() ==
          google::protobuf::io::CodedInputStream::GetDefaultRecursionLimit()) {
    parse_ok = dest.ParsePartialFromZeroCopyStream(&input_stream);
  } else {
    if (!options.merge()) dest.Clear();
    google::protobuf::io::CodedInputStream coded_stream(&input_stream);
    coded_stream.SetRecursionLimit(options.recursion_limit());
    parse_ok = dest.MergePartialFromCodedStream(&coded_stream) &&
               coded_stream.ConsumedEntireMessage();
  }
  RIEGELI_ASSERT(reader.ok())
      << "A CordReader has no reason to fail: " << reader.status();
  if (ABSL_PREDICT_FALSE(!parse_ok)) return ParseError(dest);
  return CheckInitialized(dest, options);
}

bool ReaderInputStream::Next(const void** data, int* size) {
  if (ABSL_PREDICT_FALSE(src_->pos() >=
                         Position{std::numeric_limits<int64_t>::max()})) {
    return false;
  }
  const Position max_length =
      Position{std::numeric_limits<int64_t>::max()} - src_->pos();
  if (ABSL_PREDICT_FALSE(!src_->Pull())) return false;
  *data = src_->cursor();
  *size = SaturatingIntCast<int>(UnsignedMin(src_->available(), max_length));
  src_->move_cursor(IntCast<size_t>(*size));
  return true;
}

void ReaderInputStream::BackUp(int length) {
  RIEGELI_ASSERT_GE(length, 0)
      << "Failed precondition of ZeroCopyInputStream::BackUp(): "
         "negative length";
  RIEGELI_ASSERT_LE(IntCast<size_t>(length), src_->start_to_cursor())
      << "Failed precondition of ZeroCopyInputStream::BackUp(): "
         "length larger than the amount of buffered data";
  src_->set_cursor(src_->cursor() - length);
}

bool ReaderInputStream::Skip(int length) {
  RIEGELI_ASSERT_GE(length, 0)
      << "Failed precondition of ZeroCopyInputStream::Skip(): negative length";
  const Position max_length =
      SaturatingSub(Position{std::numeric_limits<int64_t>::max()}, src_->pos());
  const size_t length_to_skip =
      UnsignedMin(IntCast<size_t>(length), max_length);
  return src_->Skip(length_to_skip) &&
         length_to_skip == IntCast<size_t>(length);
}

int64_t ReaderInputStream::ByteCount() const {
  return SaturatingIntCast<int64_t>(src_->pos());
}

}  // namespace riegeli
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: modulemanager.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 01:45:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "services/modulemanager.hxx"
#include "services/frame.hxx"

//_______________________________________________
// own includes

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_______________________________________________
// interface includes

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XCONTROLLER_HPP_
#include <com/sun/star/frame/XController.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif

//_______________________________________________
// other includes

#ifndef css
namespace css = ::com::sun::star;
#endif

namespace framework
{

/*-----------------------------------------------
    04.12.2003 09:32
-----------------------------------------------*/
DEFINE_XINTERFACE_5(ModuleManager                                   ,
                    OWeakObject                                     ,
                    DIRECT_INTERFACE(css::lang::XTypeProvider      ),
                    DIRECT_INTERFACE(css::lang::XServiceInfo       ),
                    DIRECT_INTERFACE(css::container::XNameAccess   ),
                    DIRECT_INTERFACE(css::container::XElementAccess),
                    DIRECT_INTERFACE(css::frame::XModuleManager   ))

/*-----------------------------------------------
    04.12.2003 09:32
-----------------------------------------------*/
DEFINE_XTYPEPROVIDER_5(ModuleManager                 ,
                       css::lang::XTypeProvider      ,
                       css::lang::XServiceInfo       ,
                       css::container::XNameAccess   ,
                       css::container::XElementAccess,
                       css::frame::XModuleManager   )

/*-----------------------------------------------
    04.12.2003 09:35
-----------------------------------------------*/
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(ModuleManager                   ,
                                 ::cppu::OWeakObject             ,
                                 SERVICENAME_MODULEMANAGER       ,
                                 IMPLEMENTATIONNAME_MODULEMANAGER)

/*-----------------------------------------------
    04.12.2003 09:35
-----------------------------------------------*/
DEFINE_INIT_SERVICE(
                    ModuleManager,
                    {
                        /*Attention
                            I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
                            to create a new instance of this class by our own supported service factory.
                            see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
                        */
                    }
                   )

/*-----------------------------------------------
    04.12.2003 09:30
-----------------------------------------------*/
ModuleManager::ModuleManager(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    : ThreadHelpBase(     )
    , m_xSMGR       (xSMGR)
{
}

/*-----------------------------------------------
    10.12.2003 11:59
-----------------------------------------------*/
ModuleManager::~ModuleManager()
{
    if (m_xCFG.is())
        m_xCFG.clear();
}

/*-----------------------------------------------
    10.12.2003 11:02
-----------------------------------------------*/
::rtl::OUString SAL_CALL ModuleManager::identify(const css::uno::Reference< css::uno::XInterface >& xModule)
    throw(css::lang::IllegalArgumentException,
          css::frame::UnknownModuleException,
          css::uno::RuntimeException         )
{
    // valid parameter?
    css::uno::Reference< css::frame::XFrame >      xFrame     (xModule, css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XController > xController(xModule, css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XModel >      xModel     (xModule, css::uno::UNO_QUERY);

    if (
        (!xFrame.is()     ) &&
        (!xController.is()) &&
        (!xModel.is()     )
       )
    {
        throw css::lang::IllegalArgumentException(
                ::rtl::OUString::createFromAscii("Not a XFrame, XController nor a XModel reference."),
                static_cast< ::cppu::OWeakObject* >(this),
                1);
    }

    // frame empty?
    // controller/model?
    // all needed interfaces available?
    css::uno::Reference< css::lang::XServiceInfo > xInfo;
    if (xFrame.is())
        xController = xFrame->getController();
    if (xController.is())
        xModel = xController->getModel();

    if (xModel.is())
        xInfo = css::uno::Reference< css::lang::XServiceInfo >(xModel, css::uno::UNO_QUERY);
    else if (xController.is())
        xInfo = css::uno::Reference< css::lang::XServiceInfo >(xController, css::uno::UNO_QUERY);
    else if (xFrame.is()) // needed for detection of special modules (like e.g. help)!
        xInfo = css::uno::Reference< css::lang::XServiceInfo >(xFrame, css::uno::UNO_QUERY);

    if (!xInfo.is())
        throw css::frame::UnknownModuleException(
                ::rtl::OUString::createFromAscii("Cant classify given module."),
                static_cast< ::cppu::OWeakObject* >(this));

    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    // TODO
    // Please migrate to new method impl_identifyNew() in case every office module
    // supports it right service name and can be asked directly ...

    // throws an UnknownModuleException in case module has no configuration!
    ::rtl::OUString sIdentifier = impl_identify(xInfo);
    aReadLock.unlock();
    // <- SAFE ----------------------------------
    return sIdentifier;
}

/*-----------------------------------------------
    10.12.2003 12:05
-----------------------------------------------*/
css::uno::Any SAL_CALL ModuleManager::getByName(const ::rtl::OUString& sName)
    throw(css::container::NoSuchElementException,
          css::lang::WrappedTargetException     ,
          css::uno::RuntimeException            )
{
    // get access to the element
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    css::uno::Any aElement = xCFG->getByName(sName);

    css::uno::Reference< css::container::XNameAccess > xElement;
    aElement >>= xElement;
    if (!xElement.is())
    {
        throw css::container::NoSuchElementException(
                ::rtl::OUString::createFromAscii("The module configuration seems to be corrupted."),
                static_cast< css::container::XNameAccess* >(this));
    }

    // convert it to seq< PropertyValue >!
    const css::uno::Sequence< ::rtl::OUString > lProps = xElement->getElementNames();
    const ::rtl::OUString*                      pProps = lProps.getConstArray();
          sal_Int32                             c      = lProps.getLength();

    css::uno::Sequence< css::beans::PropertyValue > lElement(c);
    css::beans::PropertyValue*                      pElement = lElement.getArray();

    for (sal_Int32 i=0; i<c; ++i)
    {
        pElement[i].Name  = pProps[i];
        pElement[i].Value = xElement->getByName(pProps[i]);
    }

    /*  TODO
        a) add some implicit properties for readonly/mandatory ...
        b) catch exception during property access ...
           But how they should be handled?
     */

    return css::uno::makeAny(lElement);
}

/*-----------------------------------------------
    10.12.2003 11:58
-----------------------------------------------*/
css::uno::Sequence< ::rtl::OUString > SAL_CALL ModuleManager::getElementNames()
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    return xCFG->getElementNames();
}

/*-----------------------------------------------
    10.12.2003 11:57
-----------------------------------------------*/
sal_Bool SAL_CALL ModuleManager::hasByName(const ::rtl::OUString& sName)
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    return xCFG->hasByName(sName);
}

/*-----------------------------------------------
    10.12.2003 11:35
-----------------------------------------------*/
css::uno::Type SAL_CALL ModuleManager::getElementType()
    throw(css::uno::RuntimeException)
{
    return ::getCppuType((const css::uno::Sequence< css::beans::PropertyValue >*)0);
}

/*-----------------------------------------------
    10.12.2003 11:56
-----------------------------------------------*/
sal_Bool SAL_CALL ModuleManager::hasElements()
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    return xCFG->hasElements();
}

/*-----------------------------------------------
    14.12.2003 09:45
-----------------------------------------------*/
css::uno::Reference< css::container::XNameAccess > ModuleManager::implts_openConfig()
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    if (m_xCFG.is())
        return m_xCFG;

    css::uno::Reference< css::uno::XInterface > xCFG;
    try
    {
        css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
            m_xSMGR->createInstance(SERVICENAME_CFGPROVIDER), css::uno::UNO_QUERY);

        if (!xConfigProvider.is())
            throw css::uno::RuntimeException(
                    ::rtl::OUString::createFromAscii("Could not locate configuration service."),
                    static_cast< css::container::XNameAccess* >(this));

        // set root path
        css::uno::Sequence< css::uno::Any > lParams(1);
        css::beans::PropertyValue           aParam;
        aParam.Name    = ::rtl::OUString::createFromAscii("nodepath");
        aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories");
        lParams[0]   <<= aParam;

        // open it
        xCFG = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS, lParams);
    }
    catch(const css::uno::RuntimeException&)
        { throw; }
    catch(const css::uno::Exception&)
        { xCFG.clear(); }

    m_xCFG = css::uno::Reference< css::container::XNameAccess >(xCFG, css::uno::UNO_QUERY);
    if (!m_xCFG.is())
    {
        throw css::uno::RuntimeException(
                ::rtl::OUString::createFromAscii("Could not open configuration package /org.openoffice.Setup/Office/Factories."),
                static_cast< css::container::XNameAccess* >(this));
    }

    return m_xCFG;
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    30.01.2004 07:54
-----------------------------------------------*/
::rtl::OUString ModuleManager::impl_identify(const css::uno::Reference< css::lang::XServiceInfo >& xModule)
    throw(css::frame::UnknownModuleException)
{
    const css::uno::Sequence< ::rtl::OUString > lKnownModules = getElementNames();
    const ::rtl::OUString*                      pKnownModules = lKnownModules.getConstArray();
          sal_Int32                             c             = lKnownModules.getLength();

    // detect modules in a generic way ...
    for (sal_Int32 m=0; m<c; ++m)
    {
        if (xModule->supportsService(pKnownModules[m]))
            return pKnownModules[m];
    }

    throw css::frame::UnknownModuleException(
            ::rtl::OUString::createFromAscii("Cant classify given module."),
            static_cast< ::cppu::OWeakObject* >(this));
}

} // namespace framework
<commit_msg>INTEGRATION: CWS pchfix02 (1.6.202); FILE MERGED 2006/09/01 17:29:20 kaib 1.6.202.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: modulemanager.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 14:11:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"

#include "services/modulemanager.hxx"
#include "services/frame.hxx"

//_______________________________________________
// own includes

#ifndef __FRAMEWORK_THREADHELP_READGUARD_HXX_
#include <threadhelp/readguard.hxx>
#endif

#ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_
#include <threadhelp/writeguard.hxx>
#endif

#ifndef __FRAMEWORK_SERVICES_H_
#include <services.h>
#endif

//_______________________________________________
// interface includes

#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
#include <com/sun/star/frame/XFrame.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XCONTROLLER_HPP_
#include <com/sun/star/frame/XController.hpp>
#endif

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif

//_______________________________________________
// other includes

#ifndef css
namespace css = ::com::sun::star;
#endif

namespace framework
{

/*-----------------------------------------------
    04.12.2003 09:32
-----------------------------------------------*/
DEFINE_XINTERFACE_5(ModuleManager                                   ,
                    OWeakObject                                     ,
                    DIRECT_INTERFACE(css::lang::XTypeProvider      ),
                    DIRECT_INTERFACE(css::lang::XServiceInfo       ),
                    DIRECT_INTERFACE(css::container::XNameAccess   ),
                    DIRECT_INTERFACE(css::container::XElementAccess),
                    DIRECT_INTERFACE(css::frame::XModuleManager   ))

/*-----------------------------------------------
    04.12.2003 09:32
-----------------------------------------------*/
DEFINE_XTYPEPROVIDER_5(ModuleManager                 ,
                       css::lang::XTypeProvider      ,
                       css::lang::XServiceInfo       ,
                       css::container::XNameAccess   ,
                       css::container::XElementAccess,
                       css::frame::XModuleManager   )

/*-----------------------------------------------
    04.12.2003 09:35
-----------------------------------------------*/
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(ModuleManager                   ,
                                 ::cppu::OWeakObject             ,
                                 SERVICENAME_MODULEMANAGER       ,
                                 IMPLEMENTATIONNAME_MODULEMANAGER)

/*-----------------------------------------------
    04.12.2003 09:35
-----------------------------------------------*/
DEFINE_INIT_SERVICE(
                    ModuleManager,
                    {
                        /*Attention
                            I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
                            to create a new instance of this class by our own supported service factory.
                            see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
                        */
                    }
                   )

/*-----------------------------------------------
    04.12.2003 09:30
-----------------------------------------------*/
ModuleManager::ModuleManager(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    : ThreadHelpBase(     )
    , m_xSMGR       (xSMGR)
{
}

/*-----------------------------------------------
    10.12.2003 11:59
-----------------------------------------------*/
ModuleManager::~ModuleManager()
{
    if (m_xCFG.is())
        m_xCFG.clear();
}

/*-----------------------------------------------
    10.12.2003 11:02
-----------------------------------------------*/
::rtl::OUString SAL_CALL ModuleManager::identify(const css::uno::Reference< css::uno::XInterface >& xModule)
    throw(css::lang::IllegalArgumentException,
          css::frame::UnknownModuleException,
          css::uno::RuntimeException         )
{
    // valid parameter?
    css::uno::Reference< css::frame::XFrame >      xFrame     (xModule, css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XController > xController(xModule, css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XModel >      xModel     (xModule, css::uno::UNO_QUERY);

    if (
        (!xFrame.is()     ) &&
        (!xController.is()) &&
        (!xModel.is()     )
       )
    {
        throw css::lang::IllegalArgumentException(
                ::rtl::OUString::createFromAscii("Not a XFrame, XController nor a XModel reference."),
                static_cast< ::cppu::OWeakObject* >(this),
                1);
    }

    // frame empty?
    // controller/model?
    // all needed interfaces available?
    css::uno::Reference< css::lang::XServiceInfo > xInfo;
    if (xFrame.is())
        xController = xFrame->getController();
    if (xController.is())
        xModel = xController->getModel();

    if (xModel.is())
        xInfo = css::uno::Reference< css::lang::XServiceInfo >(xModel, css::uno::UNO_QUERY);
    else if (xController.is())
        xInfo = css::uno::Reference< css::lang::XServiceInfo >(xController, css::uno::UNO_QUERY);
    else if (xFrame.is()) // needed for detection of special modules (like e.g. help)!
        xInfo = css::uno::Reference< css::lang::XServiceInfo >(xFrame, css::uno::UNO_QUERY);

    if (!xInfo.is())
        throw css::frame::UnknownModuleException(
                ::rtl::OUString::createFromAscii("Cant classify given module."),
                static_cast< ::cppu::OWeakObject* >(this));

    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    // TODO
    // Please migrate to new method impl_identifyNew() in case every office module
    // supports it right service name and can be asked directly ...

    // throws an UnknownModuleException in case module has no configuration!
    ::rtl::OUString sIdentifier = impl_identify(xInfo);
    aReadLock.unlock();
    // <- SAFE ----------------------------------
    return sIdentifier;
}

/*-----------------------------------------------
    10.12.2003 12:05
-----------------------------------------------*/
css::uno::Any SAL_CALL ModuleManager::getByName(const ::rtl::OUString& sName)
    throw(css::container::NoSuchElementException,
          css::lang::WrappedTargetException     ,
          css::uno::RuntimeException            )
{
    // get access to the element
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    css::uno::Any aElement = xCFG->getByName(sName);

    css::uno::Reference< css::container::XNameAccess > xElement;
    aElement >>= xElement;
    if (!xElement.is())
    {
        throw css::container::NoSuchElementException(
                ::rtl::OUString::createFromAscii("The module configuration seems to be corrupted."),
                static_cast< css::container::XNameAccess* >(this));
    }

    // convert it to seq< PropertyValue >!
    const css::uno::Sequence< ::rtl::OUString > lProps = xElement->getElementNames();
    const ::rtl::OUString*                      pProps = lProps.getConstArray();
          sal_Int32                             c      = lProps.getLength();

    css::uno::Sequence< css::beans::PropertyValue > lElement(c);
    css::beans::PropertyValue*                      pElement = lElement.getArray();

    for (sal_Int32 i=0; i<c; ++i)
    {
        pElement[i].Name  = pProps[i];
        pElement[i].Value = xElement->getByName(pProps[i]);
    }

    /*  TODO
        a) add some implicit properties for readonly/mandatory ...
        b) catch exception during property access ...
           But how they should be handled?
     */

    return css::uno::makeAny(lElement);
}

/*-----------------------------------------------
    10.12.2003 11:58
-----------------------------------------------*/
css::uno::Sequence< ::rtl::OUString > SAL_CALL ModuleManager::getElementNames()
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    return xCFG->getElementNames();
}

/*-----------------------------------------------
    10.12.2003 11:57
-----------------------------------------------*/
sal_Bool SAL_CALL ModuleManager::hasByName(const ::rtl::OUString& sName)
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    return xCFG->hasByName(sName);
}

/*-----------------------------------------------
    10.12.2003 11:35
-----------------------------------------------*/
css::uno::Type SAL_CALL ModuleManager::getElementType()
    throw(css::uno::RuntimeException)
{
    return ::getCppuType((const css::uno::Sequence< css::beans::PropertyValue >*)0);
}

/*-----------------------------------------------
    10.12.2003 11:56
-----------------------------------------------*/
sal_Bool SAL_CALL ModuleManager::hasElements()
    throw(css::uno::RuntimeException)
{
    css::uno::Reference< css::container::XNameAccess > xCFG = implts_openConfig();
    return xCFG->hasElements();
}

/*-----------------------------------------------
    14.12.2003 09:45
-----------------------------------------------*/
css::uno::Reference< css::container::XNameAccess > ModuleManager::implts_openConfig()
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    if (m_xCFG.is())
        return m_xCFG;

    css::uno::Reference< css::uno::XInterface > xCFG;
    try
    {
        css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
            m_xSMGR->createInstance(SERVICENAME_CFGPROVIDER), css::uno::UNO_QUERY);

        if (!xConfigProvider.is())
            throw css::uno::RuntimeException(
                    ::rtl::OUString::createFromAscii("Could not locate configuration service."),
                    static_cast< css::container::XNameAccess* >(this));

        // set root path
        css::uno::Sequence< css::uno::Any > lParams(1);
        css::beans::PropertyValue           aParam;
        aParam.Name    = ::rtl::OUString::createFromAscii("nodepath");
        aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories");
        lParams[0]   <<= aParam;

        // open it
        xCFG = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS, lParams);
    }
    catch(const css::uno::RuntimeException&)
        { throw; }
    catch(const css::uno::Exception&)
        { xCFG.clear(); }

    m_xCFG = css::uno::Reference< css::container::XNameAccess >(xCFG, css::uno::UNO_QUERY);
    if (!m_xCFG.is())
    {
        throw css::uno::RuntimeException(
                ::rtl::OUString::createFromAscii("Could not open configuration package /org.openoffice.Setup/Office/Factories."),
                static_cast< css::container::XNameAccess* >(this));
    }

    return m_xCFG;
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    30.01.2004 07:54
-----------------------------------------------*/
::rtl::OUString ModuleManager::impl_identify(const css::uno::Reference< css::lang::XServiceInfo >& xModule)
    throw(css::frame::UnknownModuleException)
{
    const css::uno::Sequence< ::rtl::OUString > lKnownModules = getElementNames();
    const ::rtl::OUString*                      pKnownModules = lKnownModules.getConstArray();
          sal_Int32                             c             = lKnownModules.getLength();

    // detect modules in a generic way ...
    for (sal_Int32 m=0; m<c; ++m)
    {
        if (xModule->supportsService(pKnownModules[m]))
            return pKnownModules[m];
    }

    throw css::frame::UnknownModuleException(
            ::rtl::OUString::createFromAscii("Cant classify given module."),
            static_cast< ::cppu::OWeakObject* >(this));
}

} // namespace framework
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011, Google Inc. All rights reserved.
 * Copyright (C) 2012, Samsung Electronics. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

#include "config.h"
#include "modules/navigatorcontentutils/NavigatorContentUtils.h"

#include "bindings/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Navigator.h"
#include "core/page/Page.h"
#include "wtf/HashSet.h"

namespace WebCore {

static HashSet<String>* protocolWhitelist;

static void initProtocolHandlerWhitelist()
{
    protocolWhitelist = new HashSet<String>;
    static const char* const protocols[] = {
        "bitcoin",
        "geo",
        "im",
        "irc",
        "ircs",
        "magnet",
        "mailto",
        "mms",
        "news",
        "nntp",
        "sip",
        "sms",
        "smsto",
        "ssh",
        "tel",
        "urn",
        "webcal",
        "wtai",
        "xmpp",
    };
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(protocols); ++i)
        protocolWhitelist->add(protocols[i]);
}

static bool verifyCustomHandlerURL(const KURL& baseURL, const String& url, ExceptionState& exceptionState)
{
    // The specification requires that it is a SyntaxError if the "%s" token is
    // not present.
    static const char token[] = "%s";
    int index = url.find(token);
    if (-1 == index) {
        exceptionState.throwDOMException(SyntaxError, "The url provided ('" + url + "') does not contain '%s'.");
        return false;
    }

    // It is also a SyntaxError if the custom handler URL, as created by removing
    // the "%s" token and prepending the base url, does not resolve.
    String newURL = url;
    newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);

    KURL kurl(baseURL, newURL);

    if (kurl.isEmpty() || !kurl.isValid()) {
        exceptionState.throwDOMException(SyntaxError, "The custom handler URL created by removing '%s' and prepending '" + baseURL.string() + "' is invalid.");
        return false;
    }

    return true;
}

static bool isProtocolWhitelisted(const String& scheme)
{
    if (!protocolWhitelist)
        initProtocolHandlerWhitelist();
    return protocolWhitelist->contains(scheme);
}

static bool verifyProtocolHandlerScheme(const String& scheme, const String& method, ExceptionState& exceptionState)
{
    if (scheme.startsWith("web+")) {
        // The specification requires that the length of scheme is at least five characteres (including 'web+' prefix).
        if (scheme.length() >= 5 && isValidProtocol(scheme))
            return true;
        if (!isValidProtocol(scheme))
            exceptionState.throwSecurityError("The scheme '" + scheme + "' is not a valid protocol.");
        else
            exceptionState.throwSecurityError("The scheme '" + scheme + "' is less than five characters long.");
        return false;
    }

    if (isProtocolWhitelisted(scheme))
        return true;
    exceptionState.throwSecurityError("The scheme '" + scheme + "' doesn't belong to the protocol whitelist. Please prefix non-whitelisted schemes with the string 'web+'.");
    return false;
}

NavigatorContentUtils* NavigatorContentUtils::from(Page& page)
{
    return static_cast<NavigatorContentUtils*>(Supplement<Page>::from(page, supplementName()));
}

NavigatorContentUtils::~NavigatorContentUtils()
{
}

PassOwnPtr<NavigatorContentUtils> NavigatorContentUtils::create(PassOwnPtr<NavigatorContentUtilsClient> client)
{
    return adoptPtr(new NavigatorContentUtils(client));
}

void NavigatorContentUtils::registerProtocolHandler(Navigator& navigator, const String& scheme, const String& url, const String& title, ExceptionState& exceptionState)
{
    if (!navigator.frame())
        return;

    Document* document = navigator.frame()->document();
    if (!document)
        return;

    KURL baseURL = document->baseURL();

    if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
        return;

    if (!verifyProtocolHandlerScheme(scheme, "registerProtocolHandler", exceptionState))
        return;

    ASSERT(navigator.frame()->page());
    NavigatorContentUtils::from(*navigator.frame()->page())->client()->registerProtocolHandler(scheme, baseURL, KURL(ParsedURLString, url), title);
}

static String customHandlersStateString(const NavigatorContentUtilsClient::CustomHandlersState state)
{
    DEFINE_STATIC_LOCAL(const String, newHandler, ("new"));
    DEFINE_STATIC_LOCAL(const String, registeredHandler, ("registered"));
    DEFINE_STATIC_LOCAL(const String, declinedHandler, ("declined"));

    switch (state) {
    case NavigatorContentUtilsClient::CustomHandlersNew:
        return newHandler;
    case NavigatorContentUtilsClient::CustomHandlersRegistered:
        return registeredHandler;
    case NavigatorContentUtilsClient::CustomHandlersDeclined:
        return declinedHandler;
    }

    ASSERT_NOT_REACHED();
    return String();
}

String NavigatorContentUtils::isProtocolHandlerRegistered(Navigator& navigator, const String& scheme, const String& url, ExceptionState& exceptionState)
{
    DEFINE_STATIC_LOCAL(const String, declined, ("declined"));

    if (!navigator.frame())
        return declined;

    Document* document = navigator.frame()->document();
    if (document->activeDOMObjectsAreStopped())
        return declined;

    KURL baseURL = document->baseURL();

    if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
        return declined;

    if (!verifyProtocolHandlerScheme(scheme, "isProtocolHandlerRegistered", exceptionState))
        return declined;

    ASSERT(navigator.frame()->page());
    return customHandlersStateString(NavigatorContentUtils::from(*navigator.frame()->page())->client()->isProtocolHandlerRegistered(scheme, baseURL, KURL(ParsedURLString, url)));
}

void NavigatorContentUtils::unregisterProtocolHandler(Navigator& navigator, const String& scheme, const String& url, ExceptionState& exceptionState)
{
    if (!navigator.frame())
        return;

    Document* document = navigator.frame()->document();
    KURL baseURL = document->baseURL();

    if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
        return;

    if (!verifyProtocolHandlerScheme(scheme, "unregisterProtocolHandler", exceptionState))
        return;

    ASSERT(navigator.frame()->page());
    NavigatorContentUtils::from(*navigator.frame()->page())->client()->unregisterProtocolHandler(scheme, baseURL, KURL(ParsedURLString, url));
}

const char* NavigatorContentUtils::supplementName()
{
    return "NavigatorContentUtils";
}

void provideNavigatorContentUtilsTo(Page& page, PassOwnPtr<NavigatorContentUtilsClient> client)
{
    NavigatorContentUtils::provideTo(page, NavigatorContentUtils::supplementName(), NavigatorContentUtils::create(client));
}

} // namespace WebCore
<commit_msg>Remove unnecessary null checking in NavigatorContentUtils<commit_after>/*
 * Copyright (C) 2011, Google Inc. All rights reserved.
 * Copyright (C) 2012, Samsung Electronics. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

#include "config.h"
#include "modules/navigatorcontentutils/NavigatorContentUtils.h"

#include "bindings/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Navigator.h"
#include "core/page/Page.h"
#include "wtf/HashSet.h"

namespace WebCore {

static HashSet<String>* protocolWhitelist;

static void initProtocolHandlerWhitelist()
{
    protocolWhitelist = new HashSet<String>;
    static const char* const protocols[] = {
        "bitcoin",
        "geo",
        "im",
        "irc",
        "ircs",
        "magnet",
        "mailto",
        "mms",
        "news",
        "nntp",
        "sip",
        "sms",
        "smsto",
        "ssh",
        "tel",
        "urn",
        "webcal",
        "wtai",
        "xmpp",
    };
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(protocols); ++i)
        protocolWhitelist->add(protocols[i]);
}

static bool verifyCustomHandlerURL(const KURL& baseURL, const String& url, ExceptionState& exceptionState)
{
    // The specification requires that it is a SyntaxError if the "%s" token is
    // not present.
    static const char token[] = "%s";
    int index = url.find(token);
    if (-1 == index) {
        exceptionState.throwDOMException(SyntaxError, "The url provided ('" + url + "') does not contain '%s'.");
        return false;
    }

    // It is also a SyntaxError if the custom handler URL, as created by removing
    // the "%s" token and prepending the base url, does not resolve.
    String newURL = url;
    newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);

    KURL kurl(baseURL, newURL);

    if (kurl.isEmpty() || !kurl.isValid()) {
        exceptionState.throwDOMException(SyntaxError, "The custom handler URL created by removing '%s' and prepending '" + baseURL.string() + "' is invalid.");
        return false;
    }

    return true;
}

static bool isProtocolWhitelisted(const String& scheme)
{
    if (!protocolWhitelist)
        initProtocolHandlerWhitelist();
    return protocolWhitelist->contains(scheme);
}

static bool verifyProtocolHandlerScheme(const String& scheme, const String& method, ExceptionState& exceptionState)
{
    if (scheme.startsWith("web+")) {
        // The specification requires that the length of scheme is at least five characteres (including 'web+' prefix).
        if (scheme.length() >= 5 && isValidProtocol(scheme))
            return true;
        if (!isValidProtocol(scheme))
            exceptionState.throwSecurityError("The scheme '" + scheme + "' is not a valid protocol.");
        else
            exceptionState.throwSecurityError("The scheme '" + scheme + "' is less than five characters long.");
        return false;
    }

    if (isProtocolWhitelisted(scheme))
        return true;
    exceptionState.throwSecurityError("The scheme '" + scheme + "' doesn't belong to the protocol whitelist. Please prefix non-whitelisted schemes with the string 'web+'.");
    return false;
}

NavigatorContentUtils* NavigatorContentUtils::from(Page& page)
{
    return static_cast<NavigatorContentUtils*>(Supplement<Page>::from(page, supplementName()));
}

NavigatorContentUtils::~NavigatorContentUtils()
{
}

PassOwnPtr<NavigatorContentUtils> NavigatorContentUtils::create(PassOwnPtr<NavigatorContentUtilsClient> client)
{
    return adoptPtr(new NavigatorContentUtils(client));
}

void NavigatorContentUtils::registerProtocolHandler(Navigator& navigator, const String& scheme, const String& url, const String& title, ExceptionState& exceptionState)
{
    if (!navigator.frame())
        return;

    ASSERT(navigator.frame()->document());
    KURL baseURL = navigator.frame()->document()->baseURL();

    if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
        return;

    if (!verifyProtocolHandlerScheme(scheme, "registerProtocolHandler", exceptionState))
        return;

    ASSERT(navigator.frame()->page());
    NavigatorContentUtils::from(*navigator.frame()->page())->client()->registerProtocolHandler(scheme, baseURL, KURL(ParsedURLString, url), title);
}

static String customHandlersStateString(const NavigatorContentUtilsClient::CustomHandlersState state)
{
    DEFINE_STATIC_LOCAL(const String, newHandler, ("new"));
    DEFINE_STATIC_LOCAL(const String, registeredHandler, ("registered"));
    DEFINE_STATIC_LOCAL(const String, declinedHandler, ("declined"));

    switch (state) {
    case NavigatorContentUtilsClient::CustomHandlersNew:
        return newHandler;
    case NavigatorContentUtilsClient::CustomHandlersRegistered:
        return registeredHandler;
    case NavigatorContentUtilsClient::CustomHandlersDeclined:
        return declinedHandler;
    }

    ASSERT_NOT_REACHED();
    return String();
}

String NavigatorContentUtils::isProtocolHandlerRegistered(Navigator& navigator, const String& scheme, const String& url, ExceptionState& exceptionState)
{
    DEFINE_STATIC_LOCAL(const String, declined, ("declined"));

    if (!navigator.frame())
        return declined;

    Document* document = navigator.frame()->document();
    ASSERT(document);
    if (document->activeDOMObjectsAreStopped())
        return declined;

    KURL baseURL = document->baseURL();

    if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
        return declined;

    if (!verifyProtocolHandlerScheme(scheme, "isProtocolHandlerRegistered", exceptionState))
        return declined;

    ASSERT(navigator.frame()->page());
    return customHandlersStateString(NavigatorContentUtils::from(*navigator.frame()->page())->client()->isProtocolHandlerRegistered(scheme, baseURL, KURL(ParsedURLString, url)));
}

void NavigatorContentUtils::unregisterProtocolHandler(Navigator& navigator, const String& scheme, const String& url, ExceptionState& exceptionState)
{
    if (!navigator.frame())
        return;

    ASSERT(navigator.frame()->document());
    KURL baseURL = navigator.frame()->document()->baseURL();

    if (!verifyCustomHandlerURL(baseURL, url, exceptionState))
        return;

    if (!verifyProtocolHandlerScheme(scheme, "unregisterProtocolHandler", exceptionState))
        return;

    ASSERT(navigator.frame()->page());
    NavigatorContentUtils::from(*navigator.frame()->page())->client()->unregisterProtocolHandler(scheme, baseURL, KURL(ParsedURLString, url));
}

const char* NavigatorContentUtils::supplementName()
{
    return "NavigatorContentUtils";
}

void provideNavigatorContentUtilsTo(Page& page, PassOwnPtr<NavigatorContentUtilsClient> client)
{
    NavigatorContentUtils::provideTo(page, NavigatorContentUtils::supplementName(), NavigatorContentUtils::create(client));
}

} // namespace WebCore
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <fstream>

#include <unistd.h>
#include <getopt.h>

#include <rsa-attack-lib/common_modulus.hh> // comodulus namespace
#include <rsa-attack-lib/low_exponent.hh> // lowexp namespace
#include <rsa-attack-lib/factorization_attack.hh> // factoratk namespace
#include <rsa-attack-lib/rsa-attack-lib.hh> // rsatk namespace

const std::vector<std::string> attack_types = {"factoring", "common_modulus", "other"};

void what_attack_types() {
  std::cerr << "\nType can be ";
  for (std::size_t i = 0; i < attack_types.size(); ++i) {
    std::cerr << "\'" << attack_types[i] << "\', ";
  }
  std::cerr << std::endl;
}

void usage() {
  std::cerr << "Usage is --attack [type] --pubkey1 [filename] (--pubkey2 [filename] --pubkey3 [filename] --ciphertext [filename])" << std::endl;
}

bool is_everything_correct(int file_count, int aflag, bool ioerror) {
  if (ioerror) {
    std::cerr
        << "File i/o error. Check that file exists and has correct permissions."
        << std::endl;
    return false;
  }
  if (aflag == -1) {
    std::cerr << "missing argument --attack [type]" << std::endl;
    what_attack_types();
    return false;
  }
  if(aflag == 1 && file_count < 2){
    std::cerr << "needs two filenames for the " << attack_types[aflag] << "attack" << std::endl;
    return false;
  }
  if(aflag == 2 && file_count < 4){
    std::cerr << "needs three public keys, and one ciphertext";
  }
  else if (file_count == 0) {
    std::cerr << "missing argument --pubkey1 [file_to_crack]" << std::endl;
    return false;
  }
  return true;
}

int main(int argc, char* argv[]) {
  /* options descriptor */
  static struct option longopts[] = {{"attack", required_argument, NULL, 'a'},
                                     {"ciphertext", required_argument, NULL, 'b'},
                                     {"ciphertext2", required_argument, NULL, 'c'},
                                     {"pubkey1", required_argument, NULL, 'x'},
                                     {"pubkey2", required_argument, NULL, 'y'},
                                     {"pubkey3", required_argument, NULL, 'z'},
                                     {"help", no_argument, NULL, 'h'},
                                     {NULL, 0, NULL, 0}};

  bool ioerror = false;
  int option_index = 0;
  int file_count = 0, aflag = -1, ch = 0;
  std::fstream f_1;
  std::fstream f_2;
  std::fstream f_3;
  std::fstream cipher_file, cipher_file2;
  while ((ch = getopt_long(argc, argv, "a:b:c:x:y:z:h", longopts, &option_index)) !=
         -1) {
    switch (ch) {
      case 'a': {
        for(size_t i = 0; i < attack_types.size(); ++i){
          if(attack_types[i] == optarg) {
            aflag = i;
          }
        }
        if(aflag == -1) {
          what_attack_types();
        }
        break;
      }
    case 'x': {
      file_count += 1;
      std::string fname = std::string(optarg);
      f_1.open(fname, std::ios::in);
      if (!f_1.is_open()) {
        ioerror = true;
        std::cout << fname << " : error." << std::endl;
      }

      break;
    }
    case 'y': {
      file_count += 1;

      std::string fname = std::string(optarg);
      f_2.open(fname, std::ios::in);
      if (!f_2.is_open()) {
        ioerror = true;
        std::cout << fname << " : error." << std::endl;
      }
      break;
    }
    case 'z': {
      file_count += 1;

      std::string fname = std::string(optarg);
      f_3.open(fname, std::ios::in);
      if (!f_3.is_open()) {
        ioerror = true;
        std::cout << fname << " : error." << std::endl;
      }
      break;
    }
    case 'b': {
      file_count += 1;

      std::string fname = std::string(optarg);
      cipher_file.open(fname, std::ios::in);
      if (!cipher_file.is_open()) {
        ioerror = true;
        std::cout << fname << " : error." << std::endl;
      }
      break;
    }
    case 'c': {
      file_count += 1;

      std::string fname = std::string(optarg);
      cipher_file2.open(fname, std::ios::in);
      if (!cipher_file2.is_open()) {
        std::cout << fname << " : error." << std::endl;
        ioerror = true;
      }
      break;
    }
    case 'h':
      break;
    case '?':
      break;
    default: {
      usage();
      what_attack_types();
      std::exit(EXIT_FAILURE);
    }
    }
  }

  bool good = is_everything_correct(file_count, aflag, ioerror);

  if(good){
    std::cout << "Starting decryption..." << std::endl;
    rsatk::RSA_data r_1 = rsatk::parse_rsa_file(f_1);
    if(aflag == 0) {
      factoratk::factorization_attack(r_1);
    }
    else if (aflag == 1) {
      rsatk::RSA_data r_2 = rsatk::parse_rsa_file(f_2);
      r_1.C = base64_decode(rsatk::read_cipher_text(cipher_file));
      r_2.C = base64_decode(rsatk::read_cipher_text(cipher_file2));

      comodulus::common_modulus_attack(r_1, r_2);
    }
    else if (aflag == 2) {
      rsatk::RSA_data r_2 = rsatk::parse_rsa_file(f_2);
      rsatk::RSA_data r_3 = rsatk::parse_rsa_file(f_3);
      std::string c = base64_decode(rsatk::read_cipher_text(cipher_file));
      r_1.C = r_2.C = r_3.C = c;
      lowexp::low_exponent_attack(r_1, r_2, r_3);
    }
  }

  argc -= optind;
  argv += optind;

  std::exit(EXIT_SUCCESS);
}
<commit_msg>Now has sane prompt instead of a million args<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <fstream>

#include <unistd.h>
#include <getopt.h>

#include <rsa-attack-lib/common_modulus.hh> // comodulus namespace
#include <rsa-attack-lib/low_exponent.hh> // lowexp namespace
#include <rsa-attack-lib/factorization_attack.hh> // factoratk namespace
#include <rsa-attack-lib/rsa-attack-lib.hh> // rsatk namespace

const std::vector<std::string> attack_types = {"factoring", "common_modulus", "low_exponent"};

bool is_whole_number(std::string s)
{
  for(int i = 0; i < s.size(); ++i){
    if(!(int(s[i]) >= 48 && (int)s[i] <= 57)){
      return false;
    }
  }
  return true;
}

mpz_class get_whole_number(){
  int attempts = 0;
  mpz_class n = 0;
  std::string n_str = "";
  while(attempts < 5){
    std::cout << "(Please enter a whole number):\n";
    try {
      std::cin >> n_str;

      if (!is_whole_number(n_str) || std::cin.fail()){
        throw "Sorry, I don't think that's a whole number?\n";
      }
      if (n < 0){
        throw "Sorry, no negative numbers. Try something else? \n";
      }
      //std::cin.clear();
      n = mpz_class(n_str);
      return n;
    }
    catch (const char* error) {
      std::cout << error;
      attempts++;
    }
  }
  return -1;
}

void run_factoring(){
  rsatk::RSA_data r_1;

  std::cout << "What is the n value? \n";
  r_1.n = get_whole_number();
  std::cout << "What is the e value? \n";
  r_1.e = get_whole_number();
  std::cout << "Starting decryption..." << r_1.n << r_1.e;
  factoratk::factorization_attack(r_1);
}

void run_comodulus(){
  rsatk::RSA_data r_1;
  rsatk::RSA_data r_2;

  std::cout << "What is the common n value? \n";
  r_1.n  = r_2.n = get_whole_number();

  std::cout << "What is the first message's e value? ";
  r_1.e = get_whole_number();
  std::cout << "What is the second message's e value? ";
  r_2.e = get_whole_number();
  std::cout << "Provide the first encrypted message:\n";
  std::cin >> r_1.C;
  std::cout << "Provide the second encrypted message:\n";
  std::cin >> r_2.C;
  std::cout << "Starting decryption...";
  comodulus::common_modulus_attack(r_1, r_2);
}

void run_low_exp(){
  rsatk::RSA_data r_1;
  rsatk::RSA_data r_2;
  rsatk::RSA_data r_3;

  std::cout << "What is the common e value? ";
  r_1.e = r_2.e = r_3.e = get_whole_number();
  std::cout << "What is the first n value? ";
  r_1.n = get_whole_number();
  std::cout << "What is the second n value? ";
  r_2.n = get_whole_number();
  std::cout << "What is the third n value? ";
  r_3.n = get_whole_number();
  std::cout << "Provide the first encrypted message:  \n";
  std::cin >> r_1.C;
  std::cout << "Provide the second encrypted message:  \n";
  std::cin >> r_2.C;
  std::cout << "Provide the third encrypted message:  \n";
  std::cin >> r_3.C;
  std::cout << "Starting decryption...";
  lowexp::low_exponent_attack(r_1, r_2, r_3);
}

void what_attack_types() {
  std::cerr << "\nType can be ";
  for (std::size_t i = 0; i < attack_types.size(); ++i) {
    std::cerr << "\'" << attack_types[i] << "\', ";
  }
  std::cerr << std::endl;
}

void usage() {
  std::cerr << "Usage is --attack [type] " << std::endl;
}

int main(int argc, char* argv[]) {
  /* options descriptor */
  static struct option longopts[] = {{"attack", required_argument, NULL, 'a'},
                                     {"help", no_argument, NULL, 'h'},
                                     {NULL, 0, NULL, 0}};

  bool ioerror = false;
  int option_index = 0;
  int file_count = 0, aflag = -1, ch = 0;
  while ((ch = getopt_long(argc, argv, "a:h", longopts, &option_index)) !=
         -1) {
    switch (ch) {
    case 'a': {
      for(size_t i = 0; i < attack_types.size(); ++i){
        if(attack_types[i] == optarg) {
          aflag = i;
        }
      }
      if(aflag == -1) {
        what_attack_types();
      }
      break;
    }
    case 'h':
      break;
    case '?':
      break;
    default: {
      usage();
      what_attack_types();
      std::exit(EXIT_FAILURE);
    }
    }
    argc -= optind;
    argv += optind;

  }
  if(aflag == -1){
    usage();
    what_attack_types();
    std::exit(EXIT_FAILURE);
  }

  if(aflag == 0) {
    run_factoring();
  }
  if(aflag == 1) {
    run_comodulus();
  }
  if(aflag == 2) {
    run_low_exp();
  }

  std::exit(EXIT_SUCCESS);
}

//rsatk::RSA_data r_1 = rsatk::parse_rsa_file(f_1);
//else if (aflag == 1) {
//rsatk::RSA_data r_2 = rsatk::parse_rsa_file(f_2);
//r_1.C = base64_decode(rsatk::read_cipher_text(cipher_file));
//r_2.C = base64_decode(rsatk::read_cipher_text(cipher_file2));
//
//comodulus::common_modulus_attack(r_1, r_2);
//}
//else if (aflag == 2) {
//rsatk::RSA_data r_2 = rsatk::parse_rsa_file(f_2);
//rsatk::RSA_data r_3 = rsatk::parse_rsa_file(f_3);
//std::string c = base64_decode(rsatk::read_cipher_text(cipher_file));
//r_1.C = r_2.C = r_3.C = c;
//lowexp::low_exponent_attack(r_1, r_2, r_3);
//}
//}
<|endoftext|>


<commit_before>#include "../../testing/testing.hpp"

#include "../xml_element.hpp"
#include "../osm2type.hpp"

#include "../../indexer/feature_data.hpp"
#include "../../indexer/classificator.hpp"

namespace
{
  void FillXmlElement(char const * arr[][2], size_t count, XMLElement * p)
  {
    p->parent = 0;
    for (size_t i = 0; i < count; ++i)
    {
      p->childs.push_back(XMLElement());
      p->childs.back().name = "tag";
      p->childs.back().attrs["k"] = arr[i][0];
      p->childs.back().attrs["v"] = arr[i][1];
    }
  }

  uint32_t GetType(char const * arr[2])
  {
    vector<string> path;
    path.push_back(arr[0]);
    path.push_back(arr[1]);
    return classif().GetTypeByPath(path);
  }
}

UNIT_TEST(OsmType_SkipDummy)
{
  char const * arr[][2] = {
    { "abutters", "residential" },
    { "highway", "primary" },
    { "osmarender:renderRef", "no" },
    { "ref", "E51" }
  };

  XMLElement e;
  FillXmlElement(arr, ARRAY_SIZE(arr), &e);

  FeatureParams params;
  ftype::GetNameAndType(&e, params);

  TEST_EQUAL ( params.m_Types.size(), 1, () );
  TEST_EQUAL ( params.m_Types[0], GetType(arr[1]), () );
}
<commit_msg>Fix OsmType unit test - add classificator loading.<commit_after>#include "../../testing/testing.hpp"

#include "../xml_element.hpp"
#include "../osm2type.hpp"

#include "../../indexer/feature_data.hpp"
#include "../../indexer/classificator.hpp"
#include "../../indexer/classificator_loader.hpp"

#include "../../platform/platform.hpp"

namespace
{
  void FillXmlElement(char const * arr[][2], size_t count, XMLElement * p)
  {
    p->parent = 0;
    for (size_t i = 0; i < count; ++i)
    {
      p->childs.push_back(XMLElement());
      p->childs.back().name = "tag";
      p->childs.back().attrs["k"] = arr[i][0];
      p->childs.back().attrs["v"] = arr[i][1];
    }
  }

  uint32_t GetType(char const * arr[2])
  {
    vector<string> path;
    path.push_back(arr[0]);
    path.push_back(arr[1]);
    return classif().GetTypeByPath(path);
  }
}

UNIT_TEST(OsmType_SkipDummy)
{
  Platform & p = GetPlatform();
  classificator::Read(p.GetReader("drawing_rules.bin"),
                      p.GetReader("classificator.txt"),
                      p.GetReader("visibility.txt"),
                      p.GetReader("types.txt"));

  char const * arr[][2] = {
    { "abutters", "residential" },
    { "highway", "primary" },
    { "osmarender:renderRef", "no" },
    { "ref", "E51" }
  };

  XMLElement e;
  FillXmlElement(arr, ARRAY_SIZE(arr), &e);

  FeatureParams params;
  ftype::GetNameAndType(&e, params);

  TEST_EQUAL ( params.m_Types.size(), 1, () );
  TEST_EQUAL ( params.m_Types[0], GetType(arr[1]), () );
}
<|endoftext|>


<commit_before>// Usage:
//   makeResults.C("tasks", "file_list", ""task_id, kGRID)
//   tasks : "ALL" or one/more of the following separated by space:
//     "EFF"  : TRD Tracking Efficiency
//     "EFFC" : TRD Tracking Efficiency Combined (barrel + stand alone) - only in case of simulations
//     "RES"  : TRD tracking Resolution
//     "PID"  : TRD PID - pion efficiency
//     "DET"  : Basic TRD Detector checks
//     "NOFR" : Data set does not have AliESDfriends.root
//     "NOMC" : Data set does not have Monte Carlo Informations (real data), so all tasks which rely
//              on MC information are switched off
//   file_list : is the list of the files to be processed.
//     They should contain the full path. Here is an example:
// /lustre/alice/local/TRDdata/SIM/P-Flat/TRUNK/RUN0/TRD.Performance.root
// or for GRID alien:///alice/cern.ch/user/m/mfasel/MinBiasProd/results/ppMinBias80000/1/TRD.Performance.root
//   task_id : identifier of task speciality as defined by the AddMacro.C.
//             (e.g. AddTRDresolution.C defines "" for barrel tracks, "K" for kink tracks and "SA" for stand alone tracks)
//   kGRID : specify if files are comming from a GRID collection [default kFALSE]
//
// HOW TO BUILD THE FILE LIST
//   1. locally
// ls -1 BaseDir/RUN*/TRD.Performance.root > files.lst
//
//   2. on Grid
// char *BaseDir="/alice/cern.ch/user/m/mfasel/MinBiasProd/results/ppMinBias80000/";
// TGrid::Connect("alien://");
// TGridResult *res = gGrid->Query(BaseDir, "%/TRD.Performance.root");
// TGridCollection *col = gGrid->OpenCollectionQuery(res);
// col->Reset();
// TMap *map = 0x0;
// while(map = (TMap*)col->Next()){
//   TIter it((TCollection*)map);
//   TObjString *info = 0x0;
//   while(info=(TObjString*)it()){
//     printf("alien://%s\n", col->GetLFN(info->GetString().Data()));
//   }
// }
//
// The files which will be processed are the intersection between the
// condition on the tasks and the files in the file list.
//
// Authors:
//   Alex Bercuci (A.Bercuci@gsi.de)
//   Markus Fasel (m.Fasel@gsi.de)
//

#if ! defined (__CINT__) || defined (__MAKECINT__)
#include <fstream>
#include "TError.h"
#include <TClass.h>
#include <TCanvas.h>
#include <TH1.h>
#include <TGraph.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TString.h>
#include <TROOT.h>
#include <TStyle.h>
#include <TGrid.h>
#include <TGridResult.h>
#include <TGridCollection.h>

#include "AliLog.h"

#include "PWG1/TRD/AliTRDrecoTask.h"
#include "PWG1/TRD/AliTRDcheckESD.h"

#endif

#include "AliTRDperformanceTrain.h"
#include "helper.C"
//#include "../../PWG1/macros/AddPerformanceTask.h"

Char_t *libs[] = {"libProofPlayer.so", "libANALYSIS.so", "libANALYSISalice.so", "libTENDER.so", "libPWG1.so"};
// define setup
TCanvas *c = 0x0;
Bool_t mc(kFALSE), friends(kFALSE);
Bool_t summary(kTRUE);

void processTRD(TNamed* task, const Char_t *filename);
void processESD(TNamed* task, const Char_t *filename);
void makeResults(Char_t *opt = "ALL", const Char_t *files="QAResults.root", Char_t *cid = "", Bool_t kGRID=kFALSE, Bool_t dosummary = kTRUE)
{
  if(kGRID){
    if(!gSystem->Getenv("GSHELL_ROOT")){
      Error("makeResults.C", "AliEn not initialized.");
      return;
    }
    TGrid::Connect("alien://");
  }

	// Load Libraries in interactive mode
  Int_t nlibs = static_cast<Int_t>(sizeof(libs)/sizeof(Char_t *));
  for(Int_t ilib=0; ilib<nlibs; ilib++){
    if(gSystem->Load(libs[ilib]) >= 0) continue;
    Error("makeResults.C", Form("Failed to load %s.", libs[ilib]));
    return;
  }

  mc = HasReadMCData(opt);
  friends = HasReadFriendData(opt);

  gStyle->SetOptStat(0);
  gStyle->SetOptFit(0);
  TString outputFile;
  if(!TString(files).EndsWith(".root")){
    outputFile = Form("%s/QAResults.root", gSystem->ExpandPathName("$PWD"));
    mergeProd("QAResults.root", files);
  } else {
    outputFile = files;
  }
  Int_t fSteerTask = ParseOptions(opt);

  if(!dosummary){
    summary = kFLASE;
    if(!c) c=new TCanvas("c", "Performance", 10, 10, 800, 500);
  }

  TClass *ctask = new TClass;
  AliAnalysisTask *task = 0x0;
  for(Int_t itask = NTRDQATASKS; itask--;){
    if(!TSTBIT(fSteerTask, itask)) continue;
    new(ctask) TClass(fgkTRDtaskClassName[itask]);
    task = (AliAnalysisTask*)ctask->New();
    task->SetName(Form("%s%s", task->GetName(), cid));
    printf("task %s, output file %s\n", task->GetName(), outputFile.Data());
    if(task->IsA()->InheritsFrom("AliTRDrecoTask")) processTRD(task, outputFile.Data());
    else processESD(task, outputFile.Data());
  }
  delete ctask;
  delete c;
}

//______________________________________________________
void processTRD(TNamed *otask, const Char_t *filename)
{
  printf("process[%s] : %s\n", otask->GetName(), otask->GetTitle());
  Int_t debug(0);
  AliTRDrecoTask *task = dynamic_cast<AliTRDrecoTask*>(otask);
  task->SetDebugLevel(debug);
  AliLog::SetClassDebugLevel(otask->IsA()->GetName(), debug);
  task->SetMCdata(mc);
  task->SetFriends(friends);

  //if(!task->Load(Form("%s/AnalysisResults.root", gSystem->ExpandPathName("$PWD")))){
  if(!task->Load(filename)){
    Error("makeResults.C", Form("Load data container for task %s failed.", task->GetName()));
    delete task;
    return;
  }

  if(!task->PostProcess()){
    Error("makeResults.C", Form("Processing data container for task %s failed.", task->GetName()));
    delete task;
    return;
  }
  if(summary) task->MakeSummary();
  else{
    for(Int_t ipic=0; ipic<task->GetNRefFigures(); ipic++){
      c->Clear();
      if(!task->GetRefFigure(ipic)) continue;
      c->SaveAs(Form("%s_Fig%02d.gif", task->GetName(), ipic), "gif");
    }
  }
  delete task;
}

//______________________________________________________
void processESD(TNamed *otask, const Char_t *filename)
{
  printf("process[%s] : %s\n", otask->GetName(), otask->GetTitle());

  AliTRDcheckESD *esd = dynamic_cast<AliTRDcheckESD*>(otask);
  if(!esd){
    Info("makeResults.C", Form("Processing of task %s failed.", otask->GetName()));
    delete otask;
    return;
  }
  //if(!esd->Load(Form("%s/AnalysisResults.root", gSystem->ExpandPathName("$PWD")), "TRD_Performance")){
  if(!esd->Load(filename, "TRD_Performance")){
    Error("makeResults.C", Form("Load data container for task %s failed.", esd->GetName()));
    delete esd;
    return;
  }
  esd->Terminate(NULL);

  if(summary) esd->MakeSummary();
  else{
    for(Int_t ipic(0); ipic<esd->GetNRefFigures(); ipic++){
      c->Clear();
      if(!esd->GetRefFigure(ipic)) continue;
      c->SaveAs(Form("%s_Fig%02d.gif", esd->GetName(), ipic));
    }
  }
  delete esd;
}
<commit_msg>fix typo<commit_after>// Usage:
//   makeResults.C("tasks", "file_list", ""task_id, kGRID)
//   tasks : "ALL" or one/more of the following separated by space:
//     "EFF"  : TRD Tracking Efficiency
//     "EFFC" : TRD Tracking Efficiency Combined (barrel + stand alone) - only in case of simulations
//     "RES"  : TRD tracking Resolution
//     "PID"  : TRD PID - pion efficiency
//     "DET"  : Basic TRD Detector checks
//     "NOFR" : Data set does not have AliESDfriends.root
//     "NOMC" : Data set does not have Monte Carlo Informations (real data), so all tasks which rely
//              on MC information are switched off
//   file_list : is the list of the files to be processed.
//     They should contain the full path. Here is an example:
// /lustre/alice/local/TRDdata/SIM/P-Flat/TRUNK/RUN0/TRD.Performance.root
// or for GRID alien:///alice/cern.ch/user/m/mfasel/MinBiasProd/results/ppMinBias80000/1/TRD.Performance.root
//   task_id : identifier of task speciality as defined by the AddMacro.C.
//             (e.g. AddTRDresolution.C defines "" for barrel tracks, "K" for kink tracks and "SA" for stand alone tracks)
//   kGRID : specify if files are comming from a GRID collection [default kFALSE]
//
// HOW TO BUILD THE FILE LIST
//   1. locally
// ls -1 BaseDir/RUN*/TRD.Performance.root > files.lst
//
//   2. on Grid
// char *BaseDir="/alice/cern.ch/user/m/mfasel/MinBiasProd/results/ppMinBias80000/";
// TGrid::Connect("alien://");
// TGridResult *res = gGrid->Query(BaseDir, "%/TRD.Performance.root");
// TGridCollection *col = gGrid->OpenCollectionQuery(res);
// col->Reset();
// TMap *map = 0x0;
// while(map = (TMap*)col->Next()){
//   TIter it((TCollection*)map);
//   TObjString *info = 0x0;
//   while(info=(TObjString*)it()){
//     printf("alien://%s\n", col->GetLFN(info->GetString().Data()));
//   }
// }
//
// The files which will be processed are the intersection between the
// condition on the tasks and the files in the file list.
//
// Authors:
//   Alex Bercuci (A.Bercuci@gsi.de)
//   Markus Fasel (m.Fasel@gsi.de)
//

#if ! defined (__CINT__) || defined (__MAKECINT__)
#include <fstream>
#include "TError.h"
#include <TClass.h>
#include <TCanvas.h>
#include <TH1.h>
#include <TGraph.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TString.h>
#include <TROOT.h>
#include <TStyle.h>
#include <TGrid.h>
#include <TGridResult.h>
#include <TGridCollection.h>

#include "AliLog.h"

#include "PWG1/TRD/AliTRDrecoTask.h"
#include "PWG1/TRD/AliTRDcheckESD.h"

#endif

#include "AliTRDperformanceTrain.h"
#include "helper.C"
//#include "../../PWG1/macros/AddPerformanceTask.h"

Char_t *libs[] = {"libProofPlayer.so", "libANALYSIS.so", "libANALYSISalice.so", "libTENDER.so", "libPWG1.so"};
// define setup
TCanvas *c = 0x0;
Bool_t mc(kFALSE), friends(kFALSE);
Bool_t summary(kTRUE);

void processTRD(TNamed* task, const Char_t *filename);
void processESD(TNamed* task, const Char_t *filename);
void makeResults(Char_t *opt = "ALL", const Char_t *files="QAResults.root", Char_t *cid = "", Bool_t kGRID=kFALSE, Bool_t dosummary = kTRUE)
{
  if(kGRID){
    if(!gSystem->Getenv("GSHELL_ROOT")){
      Error("makeResults.C", "AliEn not initialized.");
      return;
    }
    TGrid::Connect("alien://");
  }

	// Load Libraries in interactive mode
  Int_t nlibs = static_cast<Int_t>(sizeof(libs)/sizeof(Char_t *));
  for(Int_t ilib=0; ilib<nlibs; ilib++){
    if(gSystem->Load(libs[ilib]) >= 0) continue;
    Error("makeResults.C", Form("Failed to load %s.", libs[ilib]));
    return;
  }

  mc = HasReadMCData(opt);
  friends = HasReadFriendData(opt);

  gStyle->SetOptStat(0);
  gStyle->SetOptFit(0);
  TString outputFile;
  if(!TString(files).EndsWith(".root")){
    outputFile = Form("%s/QAResults.root", gSystem->ExpandPathName("$PWD"));
    mergeProd("QAResults.root", files);
  } else {
    outputFile = files;
  }
  Int_t fSteerTask = ParseOptions(opt);

  if(!dosummary){
    summary = kFALSE;
    if(!c) c=new TCanvas("c", "Performance", 10, 10, 800, 500);
  }

  TClass *ctask = new TClass;
  AliAnalysisTask *task = 0x0;
  for(Int_t itask = NTRDQATASKS; itask--;){
    if(!TSTBIT(fSteerTask, itask)) continue;
    new(ctask) TClass(fgkTRDtaskClassName[itask]);
    task = (AliAnalysisTask*)ctask->New();
    task->SetName(Form("%s%s", task->GetName(), cid));
    printf("task %s, output file %s\n", task->GetName(), outputFile.Data());
    if(task->IsA()->InheritsFrom("AliTRDrecoTask")) processTRD(task, outputFile.Data());
    else processESD(task, outputFile.Data());
  }
  delete ctask;
  delete c;
}

//______________________________________________________
void processTRD(TNamed *otask, const Char_t *filename)
{
  printf("process[%s] : %s\n", otask->GetName(), otask->GetTitle());
  Int_t debug(0);
  AliTRDrecoTask *task = dynamic_cast<AliTRDrecoTask*>(otask);
  task->SetDebugLevel(debug);
  AliLog::SetClassDebugLevel(otask->IsA()->GetName(), debug);
  task->SetMCdata(mc);
  task->SetFriends(friends);

  //if(!task->Load(Form("%s/AnalysisResults.root", gSystem->ExpandPathName("$PWD")))){
  if(!task->Load(filename)){
    Error("makeResults.C", Form("Load data container for task %s failed.", task->GetName()));
    delete task;
    return;
  }

  if(!task->PostProcess()){
    Error("makeResults.C", Form("Processing data container for task %s failed.", task->GetName()));
    delete task;
    return;
  }
  if(summary) task->MakeSummary();
  else{
    for(Int_t ipic=0; ipic<task->GetNRefFigures(); ipic++){
      c->Clear();
      if(!task->GetRefFigure(ipic)) continue;
      c->SaveAs(Form("%s_Fig%02d.gif", task->GetName(), ipic), "gif");
    }
  }
  delete task;
}

//______________________________________________________
void processESD(TNamed *otask, const Char_t *filename)
{
  printf("process[%s] : %s\n", otask->GetName(), otask->GetTitle());

  AliTRDcheckESD *esd = dynamic_cast<AliTRDcheckESD*>(otask);
  if(!esd){
    Info("makeResults.C", Form("Processing of task %s failed.", otask->GetName()));
    delete otask;
    return;
  }
  //if(!esd->Load(Form("%s/AnalysisResults.root", gSystem->ExpandPathName("$PWD")), "TRD_Performance")){
  if(!esd->Load(filename, "TRD_Performance")){
    Error("makeResults.C", Form("Load data container for task %s failed.", esd->GetName()));
    delete esd;
    return;
  }
  esd->Terminate(NULL);

  if(summary) esd->MakeSummary();
  else{
    for(Int_t ipic(0); ipic<esd->GetNRefFigures(); ipic++){
      c->Clear();
      if(!esd->GetRefFigure(ipic)) continue;
      c->SaveAs(Form("%s_Fig%02d.gif", esd->GetName(), ipic));
    }
  }
  delete esd;
}
<|endoftext|>