Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ matrix:
- os: osx
osx_image: xcode8.3
rust: stable
# static build
- os: linux
sudo: required
dist: xenial
rust: nightly
env: IMAGE=x86_64-alpine-linux-musl
allow_failures:
- rust: nightly

Expand Down Expand Up @@ -80,8 +86,13 @@ before_script:

script:
- |
cargo build --verbose &&
cargo test
if [[ -z "$IMAGE" ]]; then
cargo build --verbose &&
cargo test
else
docker build -t ttci-$IMAGE dist/docker/$IMAGE/ &&
docker run -v $(pwd):/tectonic ttci-$IMAGE
fi

after_success: |
if [[ "$TRAVIS_OS_NAME" == "linux" && "$TRAVIS_RUST_VERSION" == "stable" ]]; then
Expand Down
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ crate-type = ["rlib"]

[build-dependencies]
cc = "^1.0"
pkg-config = "^0.3"
pkg-config = "^0.3" # note: sync dist/docker/*/pkg-config-rs.sh with the version in Cargo.lock
regex = "^1.0"
sha2 = "^0.8"

Expand All @@ -51,13 +51,17 @@ libc = "^0.2"
tempfile = "^3.0"
md-5 = "^0.8"
sha2 = "^0.8"
serde = "^1.0"
serde_derive = "^1.0"
serde = { version = "^1.0", optional = true }
serde_derive = { version = "^1.0", optional = true }
tectonic_xdv = { path = "xdv", version = "0.1.9-dev" }
termcolor = "^1.0"
toml = "^0.4"
zip = "^0.4"

[features]
default = ["serialization"]
serialization = ["serde", "serde_derive"]

# freetype-sys = "^0.4"
# harfbuzz-sys = "^0.1"
# libz-sys = "^1.0"
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,21 @@ any given time.
Please see
[the tectonic-staging README](https://github.com/tectonic-typesetting/tectonic-staging#readme)
for more information. (Or at least, more words on the topic.)


## Features

The Tectonic build can be customized with the following features:

##### serialization (enabled by default)

This feature enables (de)serialization using the [serde](https://serde.rs/)
crate. At the moment, this is only used to read per-user configuration from a
[TOML](https://github.com/toml-lang/toml) file. If this feature is disabled,
the per-user configuration file will be silently ignored.

This functionality is optional because it requires the `serde_derive` crate,
which in turn uses Rust’s `proc_macro` feature. The `proc_macro` functionality
[is not available on musl targets](https://github.com/rust-lang/rust/issues/40174),
and so must be turned off if you wish to build a completely static Tectonic
executable.
42 changes: 42 additions & 0 deletions dist/docker/x86_64-alpine-linux-musl/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2018 The Tectonic Project
# Licensed under the MIT License.

FROM alpine:edge

RUN apk update && \
apk add \
g++ \
git \
rust \
cargo \
fontconfig-dev \
freetype-static \
glib-static \
graphite2-dev \
graphite2-static \
harfbuzz-dev \
harfbuzz-static \
icu-dev \
icu-static \
openssl-dev \
zlib-dev

ADD pkg-config-rs.sh /
RUN /pkg-config-rs.sh

ENV PKG_CONFIG_ALL_STATIC=1
ENV OPENSSL_STATIC=1
ENV OPENSSL_DIR=/usr

# cc-rs does not support static linking stdc++,
# so we omit linking information on build.rs by setting CXXSTDLIB=''
# and specify static linking in RUSTFLAGS
ENV CXXSTDLIB=""
ENV RUSTFLAGS="-L /usr/lib -l static=stdc++ -C target-feature=+crt-static"

# Use a patched pkg-config-rs to allow static linking with system libraries.
# The --no-default-features flag removes serde-derive as a dep, which doesn't
# work when linking statically (rust-lang#40147).
CMD cd /tectonic && \
echo -e "[patch.crates-io]\npkg-config = { path = \"/pkg-config-rs\" }" >> Cargo.toml && \
cargo test --release --no-default-features
25 changes: 25 additions & 0 deletions dist/docker/x86_64-alpine-linux-musl/pkg-config-rs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh
# Copyright 2018 The Tectonic Project
# Licensed under the MIT License.

set -ex

git clone --branch 0.3.14 https://github.com/alexcrichton/pkg-config-rs /pkg-config-rs

# make pkg-config-rs allows static linking with system libraries
cd /pkg-config-rs
patch -p1 <<'EOF'
diff --git a/src/lib.rs b/src/lib.rs
index 88dd310..ffcd7ae 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -547,7 +547,7 @@ fn is_static_available(name: &str, dirs: &[PathBuf]) -> bool {
};

dirs.iter().any(|dir| {
- !system_roots.iter().any(|sys| dir.starts_with(sys)) &&
+ // !system_roots.iter().any(|sys| dir.starts_with(sys)) &&
dir.join(&libname).exists()
})
}
EOF
55 changes: 39 additions & 16 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,12 @@
//! running the command-line client. So we begrudgingly have a *little*
//! configuration.

use std::io::{Read, Write};
use std::io::ErrorKind as IoErrorKind;
use std::ffi::OsStr;
use std::fs::File;
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering};

use app_dirs::{app_dir, app_root, get_app_root, sanitized, AppDataType};
use toml;
use app_dirs::{app_dir, sanitized, AppDataType};

use errors::{ErrorKind, Result};
use io::itarbundle::{HttpITarIoFactory, ITarBundle};
Expand All @@ -41,24 +38,32 @@ pub fn activate_config_test_mode(forced: bool) {
CONFIG_TEST_MODE_ACTIVATED.store(forced, Ordering::SeqCst);
}


const DEFAULT_CONFIG: &'static str = r#"[[default_bundles]]
url = "https://archive.org/services/purl/net/pkgwpub/tectonic-default"
"#;


#[derive(Deserialize)]
#[cfg_attr(feature = "serde_derive", derive(Deserialize, Serialize))]
pub struct PersistentConfig {
default_bundles: Vec<BundleInfo>,
}

#[derive(Deserialize)]
#[cfg_attr(feature = "serde_derive", derive(Deserialize, Serialize))]
pub struct BundleInfo {
url: String,
}

impl PersistentConfig {
#[cfg(feature = "serialization")]
/// Open the per-user configuration file.
///
/// This file is stored in TOML format. If the configuration file does not
/// exist, no error is signaled — instead, a basic default configuration
/// is returned. In this case, if `auto_create_config_file` is true, the
/// configuration file (and the directory containing it) will be
/// automatically created, filling in the default configuration. If it is
/// false, the default configuration is returned and the filesystem is not
/// modified.
pub fn open(auto_create_config_file: bool) -> Result<PersistentConfig> {
use toml;
use std::io::{Read, Write};
use std::io::ErrorKind as IoErrorKind;
use app_dirs::{app_root, get_app_root};
let mut cfg_path = if auto_create_config_file {
app_root(AppDataType::UserConfig, &::APP_INFO)?
} else {
Expand All @@ -75,11 +80,12 @@ impl PersistentConfig {
Err(e) => {
if e.kind() == IoErrorKind::NotFound {
// Config file didn't exist -- that's OK.
let config = PersistentConfig::default();
if auto_create_config_file {
let mut f = File::create(&cfg_path)?;
write!(f, "{}", DEFAULT_CONFIG)?;
write!(f, "{}", toml::to_string(&config)?)?;
}
toml::from_str(DEFAULT_CONFIG)?
config
} else {
// Uh oh, unexpected error reading the config file.
return Err(e.into());
Expand All @@ -90,6 +96,18 @@ impl PersistentConfig {
Ok(config)
}

#[cfg(not(feature = "serialization"))]
/// Return a default configuration structure.
///
/// In most builds of Tectonic, this function reads a per-user
/// configuration file and returns it. However, this version of Tectonic
/// has been built without the `serde` feature, so it cannot deserialize
/// the file. Therefore, this function always returns the default
/// configuration.
pub fn open(_auto_create_config_file: bool) -> Result<PersistentConfig> {
Ok(PersistentConfig::default())
}

pub fn make_cached_url_provider(&self, url: &str, only_cached: bool, status: &mut StatusBackend) -> Result<Box<Bundle>> {
let itb = ITarBundle::<HttpITarIoFactory>::new(url);

Expand Down Expand Up @@ -157,9 +175,14 @@ impl PersistentConfig {
}
}


impl Default for PersistentConfig {
fn default() -> Self {
toml::from_str(DEFAULT_CONFIG).expect("un-parseable built-in default configuration (?!)")
PersistentConfig {
default_bundles: vec![
BundleInfo {
url: String::from("https://archive.org/services/purl/net/pkgwpub/tectonic-default"),
}
]
}
}
}
1 change: 1 addition & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ error_chain! {
ParseInt(num::ParseIntError);
Persist(tempfile::PersistError);
TomlDe(toml::de::Error);
TomlSer(toml::ser::Error);
Utf8(str::Utf8Error);
Xdv(tectonic_xdv::XdvError);
Zip(ZipError);
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ extern crate hyper_native_tls;
extern crate libc;
extern crate md5;
extern crate tempfile;
#[macro_use] extern crate serde_derive;
extern crate serde;
#[cfg(feature = "serde_derive")] #[macro_use] extern crate serde_derive;
#[cfg(feature = "serde")] extern crate serde;
extern crate sha2;
extern crate tectonic_xdv;
extern crate termcolor;
Expand Down
8 changes: 4 additions & 4 deletions tectonic/dpx-dpxcrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,10 +1228,10 @@ AES_ecb_encrypt (const unsigned char *key, size_t key_len,

/* NULL iv means here "use random IV". */
void
AES_cbc_encrypt (const unsigned char *key, size_t key_len,
const unsigned char *iv, int padding,
const unsigned char *plain, size_t plain_len,
unsigned char **cipher, size_t *cipher_len)
AES_cbc_encrypt_tectonic (const unsigned char *key, size_t key_len,
const unsigned char *iv, int padding,
const unsigned char *plain, size_t plain_len,
unsigned char **cipher, size_t *cipher_len)
{
AES_CONTEXT *ctx, aes;
const unsigned char *inptr;
Expand Down
8 changes: 4 additions & 4 deletions tectonic/dpx-dpxcrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ void AES_ecb_encrypt (const unsigned char *key, size_t key_len,
const unsigned char *plain, size_t plain_len,
unsigned char **cipher, size_t *cipher_len);

void AES_cbc_encrypt (const unsigned char *key, size_t key_len,
const unsigned char *iv, int padding,
const unsigned char *plain, size_t plain_len,
unsigned char **cipher, size_t *cipher_len);
void AES_cbc_encrypt_tectonic (const unsigned char *key, size_t key_len,
const unsigned char *iv, int padding,
const unsigned char *plain, size_t plain_len,
unsigned char **cipher, size_t *cipher_len);

#endif /* _DPXCRYPT_H_ */
14 changes: 7 additions & 7 deletions tectonic/dpx-pdfencrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ compute_hash_V5 (unsigned char *hash,
Kr = NEW(K1_len * 64, unsigned char);
for (i = 0; i < 64; i++)
memcpy(Kr + i * K1_len, K1, K1_len);
AES_cbc_encrypt(K, 16, K + 16, 0, Kr, K1_len * 64, &E, &E_len);
AES_cbc_encrypt_tectonic(K, 16, K + 16, 0, Kr, K1_len * 64, &E, &E_len);
free(Kr);

for (i = 0; i < 16; i++)
Expand Down Expand Up @@ -392,7 +392,7 @@ compute_owner_password_V5 (struct pdf_sec *p, const char *oplain)

compute_hash_V5(hash, oplain, ksalt, p->U, p->R);
memset(iv, 0, AES_BLOCKSIZE);
AES_cbc_encrypt(hash, 32, iv, 0, p->key, p->key_size, &OE, &OE_len);
AES_cbc_encrypt_tectonic(hash, 32, iv, 0, p->key, p->key_size, &OE, &OE_len);
memcpy(p->OE, OE, 32);
free(OE);
}
Expand All @@ -417,7 +417,7 @@ compute_user_password_V5 (struct pdf_sec *p, const char *uplain)

compute_hash_V5(hash, uplain, ksalt, NULL, p->R);
memset(iv, 0, AES_BLOCKSIZE);
AES_cbc_encrypt(hash, 32, iv, 0, p->key, p->key_size, &UE, &UE_len);
AES_cbc_encrypt_tectonic(hash, 32, iv, 0, p->key, p->key_size, &UE, &UE_len);
memcpy(p->UE, UE, 32);
free(UE);
}
Expand Down Expand Up @@ -634,12 +634,12 @@ pdf_encrypt_data (const unsigned char *plain, size_t plain_len,
break;
case 4:
calculate_key(p, key);
AES_cbc_encrypt(key, MIN(16, p->key_size + 5), NULL, 1,
plain, plain_len, cipher, cipher_len);
AES_cbc_encrypt_tectonic(key, MIN(16, p->key_size + 5), NULL, 1,
plain, plain_len, cipher, cipher_len);
break;
case 5:
AES_cbc_encrypt(p->key, p->key_size, NULL, 1,
plain, plain_len, cipher, cipher_len);
AES_cbc_encrypt_tectonic(p->key, p->key_size, NULL, 1,
plain, plain_len, cipher, cipher_len);
break;
default:
_tt_abort("pdfencrypt: Unexpected V value: %d", p->V);
Expand Down