Repository: cossacklabs/themis (language: rust)

Issue:
Update or remove hardcoded versions inside code
`themis_version()` is used to verify that we have installed the correct version of Themis. 

However, versions are not updated to `0.10.0`
https://github.com/cossacklabs/themis/blob/master/src/soter/soter.h#L33
https://github.com/cossacklabs/themis/blob/master/src/themis/themis.h#L33

Thank you @ilammy for finding this


Discussion / hints:
We got internal conversation that we would remove hardcoded versions at all.

@ilammy I know you were using version check function, don't you mind if we remove it? :))
Hm... After giving it some thought I believe that `themis_version()` function by itself has little practical value and can be removed. However, it may be useful to have the version available somewhere.

This function returns a human-readable string which is not really expected to be consumed by programs. Sure, it may be useful for printing out some banner at application startup, but if one wants to check Themis version at run-time they would rather have a more convenient API like this one:

```c
int themis_version_major(void);
int themis_version_minor(void);
int themis_version_patch(void);
```
Integers are immediately usable, you don't need to parse them.

Though, I kinda struggle to come up with a legitimate use-case for checking Themis version at run-time. It's far more likely to have a need for compile-time checks instead. For example, having some preprocessor defines enables writing code that compiles with different versions of Themis:

```c
#if THEMIS_VERSION_CODE < THEMIS_VERSION(0,10,0)
    themis_legacy_api();
#else
    themis_modern_api();
#endif
```

Versions are also important for API/ABI compatibility when dynamically-linked libraries are involved. Shared objects should include the version field so that dynamic linker may load an appropriate library and refuse to load incompatible ones. Incidentally, Themis currently does _not_ include a version field in its shared libraries (soname), so it is possible to accidentally break applications by making incompatible changes in API or ABI. (I guess this is worth creating another issue...)

I personally use `themis_version()` mostly as a sanity test. It is redundant to download the source code for Themis v0.10, build it, and then check that you have indeed built Themis v0.10. It's a nice safety check, but not a critical one.

Fix patch:
diff --git a/src/soter/boringssl/soter.c b/src/soter/boringssl/soter.c
deleted file mode 100644
index 4a81edb36..000000000
--- a/src/soter/boringssl/soter.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-* Copyright (c) 2015 Cossack Labs Limited
-*
-* 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 <soter/soter.h>
-
-#include <openssl/crypto.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#define SOTER_VERSION_TEXT_LENGTH sizeof(SOTER_VERSION_TEXT)
-
-char soter_version_text[256]=SOTER_VERSION_TEXT;
-
-const char* soter_version(){
-    memcpy(soter_version_text+SOTER_VERSION_TEXT_LENGTH-1, SSLeay_version(SSLEAY_VERSION), strlen(SSLeay_version(SSLEAY_VERSION))+1);
-    return soter_version_text;
-}
\ No newline at end of file
diff --git a/src/soter/openssl/soter.c b/src/soter/openssl/soter.c
deleted file mode 100644
index 4a81edb36..000000000
--- a/src/soter/openssl/soter.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-* Copyright (c) 2015 Cossack Labs Limited
-*
-* 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 <soter/soter.h>
-
-#include <openssl/crypto.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#define SOTER_VERSION_TEXT_LENGTH sizeof(SOTER_VERSION_TEXT)
-
-char soter_version_text[256]=SOTER_VERSION_TEXT;
-
-const char* soter_version(){
-    memcpy(soter_version_text+SOTER_VERSION_TEXT_LENGTH-1, SSLeay_version(SSLEAY_VERSION), strlen(SSLeay_version(SSLEAY_VERSION))+1);
-    return soter_version_text;
-}
\ No newline at end of file
diff --git a/src/soter/soter.h b/src/soter/soter.h
index d62f79abc..13fc99b6d 100644
--- a/src/soter/soter.h
+++ b/src/soter/soter.h
@@ -30,8 +30,6 @@
  * @{
  */
 
-#define SOTER_VERSION_TEXT "soter 0.9: "
-
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdlib.h>
@@ -47,12 +45,5 @@
 #include <soter/soter_asym_sign.h>
 #include <soter/soter_kdf.h>
 
-/** 
- *  @brief get version string of soter
- * 
- *  @return version string
- *
- */
-const char* soter_version(void);
 /**@}*/
 #endif /* SOTER_H */
diff --git a/src/themis/themis.c b/src/themis/themis.c
deleted file mode 100644
index c40781064..000000000
--- a/src/themis/themis.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-* Copyright (c) 2015 Cossack Labs Limited
-*
-* 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 <themis/themis.h>
-#include <soter/soter.h>
-#include <stdio.h>
-#include <string.h>
-
-#define THEMIS_VERSION_TEXT_LENGTH sizeof(THEMIS_VERSION_TEXT)
-
-char themis_version_text[1024]=THEMIS_VERSION_TEXT;
-
-const char* themis_version(){
-    memcpy(themis_version_text+THEMIS_VERSION_TEXT_LENGTH-1, soter_version(), strlen(soter_version())+2);
-    return themis_version_text;
-}
\ No newline at end of file
diff --git a/src/themis/themis.h b/src/themis/themis.h
index 2d47a6bef..149a6dcfe 100644
--- a/src/themis/themis.h
+++ b/src/themis/themis.h
@@ -30,16 +30,12 @@
  * @{
  */
 
-#define THEMIS_VERSION_TEXT "themis 0.9: "
-
 #include <themis/themis_error.h>
 #include <themis/secure_message.h>
 #include <themis/secure_cell.h>
 #include <themis/secure_session.h>
 #include <themis/secure_comparator.h>
 
-const char* themis_version(void);
-
 /** @} */
 #endif /* THEMIS_H */
 
diff --git a/src/wrappers/themis/ruby/lib/rubythemis.rb b/src/wrappers/themis/ruby/lib/rubythemis.rb
index 981edb549..88b8c8389 100644
--- a/src/wrappers/themis/ruby/lib/rubythemis.rb
+++ b/src/wrappers/themis/ruby/lib/rubythemis.rb
@@ -67,7 +67,6 @@ class CallbacksStruct < FFI::Struct
                   [:pointer, :pointer, :pointer, :pointer], :int
   attach_function :themis_gen_ec_key_pair,
                   [:pointer, :pointer, :pointer, :pointer], :int
-  attach_function :themis_version, [], :string
 
   attach_function :themis_secure_cell_encrypt_seal,
                   [:pointer, :int, :pointer, :int, :pointer, :int,


Test patch:
diff --git a/src/wrappers/themis/rust/libthemis-sys/tests/sanity.rs b/src/wrappers/themis/rust/libthemis-sys/tests/sanity.rs
index a16490b12..8356e9116 100644
--- a/src/wrappers/themis/rust/libthemis-sys/tests/sanity.rs
+++ b/src/wrappers/themis/rust/libthemis-sys/tests/sanity.rs
@@ -12,14 +12,22 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use std::ffi::CStr;
+use std::ptr;
 
 #[test]
-fn check_version() {
-    let version = unsafe { CStr::from_ptr(libthemis_sys::themis_version()) };
-    // Themis 0.10.0 is slightly buggy and identifies itself as 0.9.
-    assert!(version
-        .to_str()
-        .expect("valid UTF-8")
-        .contains("themis 0.9"));
+fn check_ffi_call() {
+    let mut private_key_len = 0;
+    let mut public_key_len = 0;
+    let status = unsafe {
+        libthemis_sys::themis_gen_ec_key_pair(
+            ptr::null_mut(),
+            &mut private_key_len,
+            ptr::null_mut(),
+            &mut public_key_len,
+        )
+    };
+    assert_eq!(
+        status,
+        libthemis_sys::THEMIS_BUFFER_TOO_SMALL as libthemis_sys::themis_status_t
+    );
 }
diff --git a/tests/themis/themis_test.c b/tests/themis/themis_test.c
index fded498ec..1ab9d4495 100644
--- a/tests/themis/themis_test.c
+++ b/tests/themis/themis_test.c
@@ -22,7 +22,6 @@ int main(int argc, char* argv[])
 {
   UNUSED(argc);
   UNUSED(argv);
-  printf("%s\n", themis_version());
   testsuite_start_testing();
 
   run_secure_message_test();