diff --git a/README.md b/README.md
index 989628e..28f59b3 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,18 @@ AndroidMagic(使用LibMagic识别文件类型)
==================
An android project to query file info with LibMagic
+[![Travis](https://img.shields.io/appveyor/ci/gruntjs/grunt.svg)](https://github.com/huzongyao/AndroidMagic/releases)
+[![Travis](https://img.shields.io/badge/file-v5.36-brightgreen.svg)](https://github.com/file/file)
+
+### Introduction
+The file command is "a file type guesser", that is, a command-line tool that tells you in words
+ what kind of data a file contains. Unlike most GUI systems, command-line UNIX systems - with this
+ program leading the charge - don't rely on filename extentions to tell you the type of a file,
+ but look at the file's actual contents. This is, of course, more reliable, but requires a bit of I/O.
+
+### Screenshot
+![screenshot](https://github.com/huzongyao/AndroidMagic/blob/master/misc/screen.gif?raw=true)
+
### Details
This project is for me to learn Java, NDK, and for fun.
* learn how to build ndk and sign apk with android gradle-experimental
@@ -9,8 +21,9 @@ This project is for me to learn Java, NDK, and for fun.
* libmagic is "a file type guesser", that tells you in words what kind of data a file contains
### 学习记录
+* 使用libmagic,我们不用看文件的后缀,就可以识别出常用文件类型
* 移植LibMagic到安卓平台上, 使文件类型的识别不仅通过扩展名
-* 使用gradle-experimental编译NDK
+* 使用cmake编译NDK
* Java与本地代码之间内存拷贝GetByteArrayRegion
* butterknife 以及 rxjava的使用
@@ -18,9 +31,6 @@ This project is for me to learn Java, NDK, and for fun.
* Official Site: http://www.darwinsys.com/file/
* GitHub:https://github.com/file/file
-### Screenshot
-![screenshot](https://github.com/huzongyao/AndroidMagic/blob/master/misc/screen.gif?raw=true)
-
### About Me
* GitHub: [https://huzongyao.github.io/](https://huzongyao.github.io/)
* ITEye博客:[http://hzy3774.iteye.com/](http://hzy3774.iteye.com/)
diff --git a/app/build.gradle b/app/build.gradle
index fc535ca..f248562 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,8 +1,7 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 27
- buildToolsVersion "27.0.3"
+ compileSdkVersion 28
signingConfigs {
demokey {
@@ -15,10 +14,9 @@ android {
defaultConfig {
applicationId "com.hzy.magic.app"
minSdkVersion 15
- targetSdkVersion 27
+ targetSdkVersion 28
versionCode 2
- versionName "1.0.1"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ versionName "1.1.1"
}
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
@@ -35,20 +33,26 @@ android {
signingConfig signingConfigs.demokey
}
}
+ applicationVariants.all { variant ->
+ variant.outputs.all {
+ def fileName = project.name + '-' + variant.name + '-V' +
+ defaultConfig.versionName + ".apk"
+ outputFileName = fileName
+ }
+ }
+ lintOptions {
+ abortOnError false
+ }
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- testImplementation 'junit:junit:4.12'
- androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- implementation 'com.android.support:appcompat-v7:27.1.1'
- implementation 'com.android.support:cardview-v7:27.1.1'
- implementation 'com.android.support:design:27.1.1'
- implementation 'com.blankj:utilcode:1.16.1'
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation 'com.android.support:cardview-v7:28.0.0'
+ implementation 'com.android.support:design:28.0.0'
+ implementation 'com.blankj:utilcode:1.23.7'
api 'io.reactivex.rxjava2:rxandroid:2.0.2'
- api 'com.jakewharton:butterknife:8.8.1'
- annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
+ api 'com.jakewharton:butterknife:9.0.0'
+ annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0'
implementation project(':libmagic')
}
diff --git a/app/src/androidTest/java/com/hzy/magic/app/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/hzy/magic/app/ExampleInstrumentedTest.java
deleted file mode 100644
index d751092..0000000
--- a/app/src/androidTest/java/com/hzy/magic/app/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.hzy.magic.app;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumentation test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.hzy.magic.app", appContext.getPackageName());
- }
-}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9b1495c..146fb71 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
@@ -10,7 +11,8 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
- android:theme="@style/AppTheme">
+ android:theme="@style/AppTheme"
+ tools:ignore="GoogleAppIndexingWarning">
diff --git a/app/src/main/java/com/hzy/magic/app/activity/MainActivity.java b/app/src/main/java/com/hzy/magic/app/activity/MainActivity.java
index 61caf3e..2de7cf8 100644
--- a/app/src/main/java/com/hzy/magic/app/activity/MainActivity.java
+++ b/app/src/main/java/com/hzy/magic/app/activity/MainActivity.java
@@ -1,6 +1,6 @@
package com.hzy.magic.app.activity;
-import android.Manifest;
+import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ProgressDialog;
import android.os.Build;
@@ -15,6 +15,7 @@
import android.view.MenuItem;
import android.view.View;
+import com.blankj.utilcode.constant.PermissionConstants;
import com.blankj.utilcode.util.PermissionUtils;
import com.hzy.libmagic.MagicApi;
import com.hzy.magic.app.R;
@@ -61,7 +62,7 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initUI();
- PermissionUtils.permission(Manifest.permission.READ_EXTERNAL_STORAGE)
+ PermissionUtils.permission(PermissionConstants.STORAGE)
.callback(new PermissionUtils.SimpleCallback() {
@Override
public void onGranted() {
@@ -80,12 +81,14 @@ private void initUI() {
mProgressDialog.setCancelable(false);
mProgressDialog.setTitle("Please Wait...");
mPathList.setAdapter(mPathAdapter = new PathItemAdapter(this, this));
- mPathList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
+ mPathList.setLayoutManager(new LinearLayoutManager(this,
+ LinearLayoutManager.HORIZONTAL, false));
mFileList.setAdapter(mFileAdapter = new FileItemAdapter(this, this));
mFileList.setLayoutManager(new LinearLayoutManager(this));
mSwipeRefresh.setOnRefreshListener(this);
}
+ @SuppressLint("CheckResult")
private void loadInitPath() {
final String path = Environment.getExternalStorageDirectory().getPath();
Observable.create((ObservableOnSubscribe>) e -> {
@@ -98,6 +101,7 @@ private void loadInitPath() {
.subscribe(this);
}
+ @SuppressLint("CheckResult")
private void loadPathInfo(final String path) {
Observable.create((ObservableOnSubscribe>) e -> {
List infoList = FileUtils.getInfoListFromPath(path);
@@ -132,6 +136,11 @@ public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ }
+
private boolean initMagicFromAssets() {
try {
InputStream inputStream = getAssets().open("magic.mgc");
@@ -168,7 +177,7 @@ public void onRefresh() {
}
@Override
- public void accept(List fileInfos) throws Exception {
+ public void accept(List fileInfos) {
mFileAdapter.setDataList(fileInfos);
mPathAdapter.setPathView(mCurPath);
mPathList.scrollToPosition(mPathAdapter.getItemCount() - 1);
diff --git a/app/src/main/java/com/hzy/magic/app/adapter/FileItemAdapter.java b/app/src/main/java/com/hzy/magic/app/adapter/FileItemAdapter.java
index 89652ef..7196080 100644
--- a/app/src/main/java/com/hzy/magic/app/adapter/FileItemAdapter.java
+++ b/app/src/main/java/com/hzy/magic/app/adapter/FileItemAdapter.java
@@ -35,7 +35,8 @@ public FileItemAdapter(Activity activity, View.OnClickListener listener) {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View rootView = LayoutInflater.from(mActivity).inflate(R.layout.storage_list_item, parent, false);
+ View rootView = LayoutInflater.from(mActivity)
+ .inflate(R.layout.storage_list_item, parent, false);
rootView.setOnClickListener(mItemClickListener);
return new ViewHolder(rootView);
}
diff --git a/app/src/main/java/com/hzy/magic/app/adapter/PathItemAdapter.java b/app/src/main/java/com/hzy/magic/app/adapter/PathItemAdapter.java
index bf6ecea..1d45b2d 100644
--- a/app/src/main/java/com/hzy/magic/app/adapter/PathItemAdapter.java
+++ b/app/src/main/java/com/hzy/magic/app/adapter/PathItemAdapter.java
@@ -1,6 +1,7 @@
package com.hzy.magic.app.adapter;
import android.app.Activity;
+import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
@@ -39,20 +40,21 @@ public void setPathView(String path) {
}
@Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View rootView = LayoutInflater.from(mActivity).inflate(R.layout.path_list_item, parent, false);
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View rootView = LayoutInflater.from(mActivity)
+ .inflate(R.layout.path_list_item, parent, false);
rootView.setOnClickListener(mItemClickListener);
return new ViewHolder(rootView);
}
@Override
- public void onBindViewHolder(ViewHolder holder, int position) {
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String item = mPathStringList[position];
- String curPath = "";
+ StringBuilder curPath = new StringBuilder();
for (int i = 0; i < position + 1; i++) {
- curPath += mPathStringList[i] + File.separator;
+ curPath.append(mPathStringList[i]).append(File.separator);
}
- holder.itemView.setTag(curPath);
+ holder.itemView.setTag(curPath.toString());
holder.pathText.setText(item);
}
diff --git a/app/src/test/java/com/hzy/magic/app/ExampleUnitTest.java b/app/src/test/java/com/hzy/magic/app/ExampleUnitTest.java
deleted file mode 100644
index 68c7630..0000000
--- a/app/src/test/java/com/hzy/magic/app/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.hzy.magic.app;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 55db43f..ae9fbaf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.4'
+ classpath 'com.android.tools.build:gradle:3.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 5670ebe..f90d248 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
diff --git a/libmagic/build.gradle b/libmagic/build.gradle
index 0aa1625..e713296 100644
--- a/libmagic/build.gradle
+++ b/libmagic/build.gradle
@@ -1,20 +1,19 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 27
- buildToolsVersion "27.0.3"
+ compileSdkVersion 28
defaultConfig {
minSdkVersion 15
- targetSdkVersion 27
+ targetSdkVersion 28
versionCode 2
- versionName "1.1.0"
+ versionName "1.1.1"
ndk {
- abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86'
+ abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86'
}
externalNativeBuild {
cmake {
- arguments '-DANDROID_PLATFORM=android-18'
+ arguments '-DANDROID_PLATFORM=android-21'
}
}
}
@@ -36,8 +35,4 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- testImplementation 'junit:junit:4.12'
}
diff --git a/libmagic/src/androidTest/java/com/hzy/libmagic/ExampleInstrumentedTest.java b/libmagic/src/androidTest/java/com/hzy/libmagic/ExampleInstrumentedTest.java
deleted file mode 100644
index cea170f..0000000
--- a/libmagic/src/androidTest/java/com/hzy/libmagic/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.hzy.libmagic;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumentation test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("com.hzy.libmagic.test", appContext.getPackageName());
- }
-}
diff --git a/libmagic/src/main/assets/magic.mgc.gz b/libmagic/src/main/assets/magic.mgc.gz
index efbcab0..0699416 100644
Binary files a/libmagic/src/main/assets/magic.mgc.gz and b/libmagic/src/main/assets/magic.mgc.gz differ
diff --git a/libmagic/src/main/cpp/file/apprentice.c b/libmagic/src/main/cpp/file/apprentice.c
index ea8d0b2..eca3ae0 100644
--- a/libmagic/src/main/cpp/file/apprentice.c
+++ b/libmagic/src/main/cpp/file/apprentice.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 THE AUTHOR AND 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
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.283 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -40,9 +40,7 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 christos Exp $")
#ifdef HAVE_UNISTD_H
#include
#endif
-#ifdef HAVE_STDDEF_H
#include
-#endif
#include
#include
#include
@@ -51,20 +49,13 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 christos Exp $")
#include
#endif
#include
-#if defined(HAVE_LIMITS_H)
#include
-#endif
-#ifndef SSIZE_MAX
-#define MAXMAGIC_SIZE ((ssize_t)0x7fffffff)
-#else
-#define MAXMAGIC_SIZE SSIZE_MAX
-#endif
-#define EATAB {while (isascii((unsigned char) *l) && \
- isspace((unsigned char) *l)) ++l;}
-#define LOWCASE(l) (isupper((unsigned char) (l)) ? \
- tolower((unsigned char) (l)) : (l))
+#define EATAB {while (isascii(CAST(unsigned char, *l)) && \
+ isspace(CAST(unsigned char, *l))) ++l;}
+#define LOWCASE(l) (isupper(CAST(unsigned char, l)) ? \
+ tolower(CAST(unsigned char, l)) : (l))
/*
* Work around a bug in headers on Digital Unix.
* At least confirmed for: OSF1 V4.0 878
@@ -83,15 +74,15 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.272 2018/06/22 20:39:50 christos Exp $")
#define MAP_FILE 0
#endif
-#define ALLOC_CHUNK (size_t)10
-#define ALLOC_INCR (size_t)200
+#define ALLOC_CHUNK CAST(size_t, 10)
+#define ALLOC_INCR CAST(size_t, 200)
#define MAP_TYPE_USER 0
#define MAP_TYPE_MALLOC 1
#define MAP_TYPE_MMAP 2
struct magic_entry {
- struct magic *mp;
+ struct magic *mp;
uint32_t cont_count;
uint32_t max_count;
};
@@ -126,7 +117,7 @@ private int apprentice_1(struct magic_set *, const char *, int);
private size_t apprentice_magic_strength(const struct magic *);
private int apprentice_sort(const void *, const void *);
private void apprentice_list(struct mlist *, int );
-private struct magic_map *apprentice_load(struct magic_set *,
+private struct magic_map *apprentice_load(struct magic_set *,
const char *, int);
private struct mlist *mlist_alloc(void);
private void mlist_free(struct mlist *);
@@ -300,12 +291,21 @@ get_type(const struct type_tbl_s *tbl, const char *l, const char **t)
return p->type;
}
+private off_t
+maxoff_t(void) {
+ if (/*CONSTCOND*/sizeof(off_t) == sizeof(int))
+ return CAST(off_t, INT_MAX);
+ if (/*CONSTCOND*/sizeof(off_t) == sizeof(long))
+ return CAST(off_t, LONG_MAX);
+ return 0x7fffffff;
+}
+
private int
get_standard_integer_type(const char *l, const char **t)
{
int type;
- if (isalpha((unsigned char)l[1])) {
+ if (isalpha(CAST(unsigned char, l[1]))) {
switch (l[1]) {
case 'C':
/* "dC" and "uC" */
@@ -340,7 +340,7 @@ get_standard_integer_type(const char *l, const char **t)
return FILE_INVALID;
}
l += 2;
- } else if (isdigit((unsigned char)l[1])) {
+ } else if (isdigit(CAST(unsigned char, l[1]))) {
/*
* "d{num}" and "u{num}"; we only support {num} values
* of 1, 2, 4, and 8 - the Single UNIX Specification
@@ -351,7 +351,7 @@ get_standard_integer_type(const char *l, const char **t)
* neither of them support values bigger than 8 or
* non-power-of-2 values.
*/
- if (isdigit((unsigned char)l[2])) {
+ if (isdigit(CAST(unsigned char, l[2]))) {
/* Multi-digit, so > 9 */
return FILE_INVALID;
}
@@ -437,8 +437,8 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
if (magicsize != FILE_MAGICSIZE) {
file_error(ms, 0, "magic element size %lu != %lu",
- (unsigned long)sizeof(*map->magic[0]),
- (unsigned long)FILE_MAGICSIZE);
+ CAST(unsigned long, sizeof(*map->magic[0])),
+ CAST(unsigned long, FILE_MAGICSIZE));
return -1;
}
@@ -451,7 +451,7 @@ apprentice_1(struct magic_set *ms, const char *fn, int action)
#ifndef COMPILE_ONLY
map = apprentice_map(ms, fn);
- if (map == (struct magic_map *)-1)
+ if (map == RCAST(struct magic_map *, -1))
return -1;
if (map == NULL) {
if (ms->flags & MAGIC_CHECK)
@@ -503,7 +503,7 @@ file_ms_alloc(int flags)
struct magic_set *ms;
size_t i, len;
- if ((ms = CAST(struct magic_set *, calloc((size_t)1,
+ if ((ms = CAST(struct magic_set *, calloc(CAST(size_t, 1u),
sizeof(struct magic_set)))) == NULL)
return NULL;
@@ -581,6 +581,14 @@ mlist_alloc(void)
return mlist;
}
+private void
+mlist_free_one(struct mlist *ml)
+{
+ if (ml->map)
+ apprentice_unmap(CAST(struct magic_map *, ml->map));
+ free(ml);
+}
+
private void
mlist_free(struct mlist *mlist)
{
@@ -589,14 +597,11 @@ mlist_free(struct mlist *mlist)
if (mlist == NULL)
return;
- ml = mlist->next;
- for (ml = mlist->next; (next = ml->next) != NULL; ml = next) {
- if (ml->map)
- apprentice_unmap(CAST(struct magic_map *, ml->map));
- free(ml);
- if (ml == mlist)
- break;
+ for (ml = mlist->next; ml != mlist; ml = next) {
+ next = ml->next;
+ mlist_free_one(ml);
}
+ mlist_free_one(mlist);
}
#ifndef COMPILE_ONLY
@@ -826,7 +831,7 @@ typesize(int type)
case FILE_LEDOUBLE:
return 8;
default:
- return (size_t)~0;
+ return CAST(size_t, ~0);
}
}
@@ -836,8 +841,9 @@ typesize(int type)
private size_t
apprentice_magic_strength(const struct magic *m)
{
-#define MULT 10
- size_t ts, v, val = 2 * MULT; /* baseline strength */
+#define MULT 10U
+ size_t ts, v;
+ ssize_t val = 2 * MULT; /* baseline strength */
switch (m->type) {
case FILE_DEFAULT: /* make sure this sorts last */
@@ -880,7 +886,7 @@ apprentice_magic_strength(const struct magic *m)
case FILE_BEDOUBLE:
case FILE_LEDOUBLE:
ts = typesize(m->type);
- if (ts == (size_t)~0)
+ if (ts == CAST(size_t, ~0))
abort();
val += ts * MULT;
break;
@@ -896,6 +902,8 @@ apprentice_magic_strength(const struct magic *m)
break;
case FILE_SEARCH:
+ if (m->vallen == 0)
+ break;
val += m->vallen * MAX(MULT / m->vallen, 1);
break;
@@ -943,9 +951,6 @@ apprentice_magic_strength(const struct magic *m)
abort();
}
- if (val == 0) /* ensure we only return 0 for FILE_DEFAULT */
- val = 1;
-
switch (m->factor_op) {
case FILE_FACTOR_OP_NONE:
break;
@@ -965,6 +970,9 @@ apprentice_magic_strength(const struct magic *m)
abort();
}
+ if (val <= 0) /* ensure we only return 0 for FILE_DEFAULT */
+ val = 1;
+
/*
* Magic entries with no description get a bonus because they depend
* on subsequent magic entries to print something.
@@ -974,7 +982,7 @@ apprentice_magic_strength(const struct magic *m)
return val;
}
-/*
+/*
* Sort callback for sorting entries by "strength" (basically length)
*/
private int
@@ -992,7 +1000,7 @@ apprentice_sort(const void *a, const void *b)
return 1;
}
-/*
+/*
* Shows sorted patterns list in the order which is used for the matching
*/
private void
@@ -1088,12 +1096,12 @@ set_test_type(struct magic *mstart, struct magic *m)
mstart->flag |= BINTEST;
if (mstart->str_flags & STRING_TEXTTEST)
mstart->flag |= TEXTTEST;
-
+
if (mstart->flag & (TEXTTEST|BINTEST))
break;
/* binary test if pattern is not text */
- if (file_looks_utf8(m->value.us, (size_t)m->vallen, NULL,
+ if (file_looks_utf8(m->value.us, CAST(size_t, m->vallen), NULL,
NULL) <= 0)
mstart->flag |= BINTEST;
else
@@ -1174,7 +1182,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
size_t i;
for (i = 0; bang[i].name != NULL; i++) {
- if ((size_t)(len - 2) > bang[i].len &&
+ if (CAST(size_t, len - 2) > bang[i].len &&
memcmp(bang[i].name, line + 2,
bang[i].len) == 0)
break;
@@ -1227,7 +1235,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
private int
cmpstrp(const void *p1, const void *p2)
{
- return strcmp(*(char *const *)p1, *(char *const *)p2);
+ return strcmp(*RCAST(char *const *, p1), *RCAST(char *const *, p2));
}
@@ -1253,10 +1261,10 @@ set_text_binary(struct magic_set *ms, struct magic_entry *me, uint32_t nme,
if (me[i].mp->flag & BINTEST) {
char *p = strstr(me[i].mp->desc, text);
if (p && (p == me[i].mp->desc ||
- isspace((unsigned char)p[-1])) &&
+ isspace(CAST(unsigned char, p[-1]))) &&
(p + len - me[i].mp->desc == MAXstring
|| (p[len] == '\0' ||
- isspace((unsigned char)p[len]))))
+ isspace(CAST(unsigned char, p[len])))))
(void)fprintf(stderr, "*** Possible "
"binary test for text type\n");
}
@@ -1280,7 +1288,7 @@ set_last_default(struct magic_set *ms, struct magic_entry *me, uint32_t nme)
file_magwarn(ms,
"level 0 \"default\" did not sort last");
}
- return;
+ return;
}
}
}
@@ -1387,12 +1395,14 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
filearr[files++] = mfn;
}
closedir(dir);
- qsort(filearr, files, sizeof(*filearr), cmpstrp);
- for (i = 0; i < files; i++) {
- load_1(ms, action, filearr[i], &errs, mset);
- free(filearr[i]);
+ if (filearr) {
+ qsort(filearr, files, sizeof(*filearr), cmpstrp);
+ for (i = 0; i < files; i++) {
+ load_1(ms, action, filearr[i], &errs, mset);
+ free(filearr[i]);
+ }
+ free(filearr);
}
- free(filearr);
} else
load_1(ms, action, fn, &errs, mset);
if (errs)
@@ -1450,12 +1460,12 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
* the sign extension must have happened.
*/
case FILE_BYTE:
- v = (signed char) v;
+ v = CAST(signed char, v);
break;
case FILE_SHORT:
case FILE_BESHORT:
case FILE_LESHORT:
- v = (short) v;
+ v = CAST(short, v);
break;
case FILE_DATE:
case FILE_BEDATE:
@@ -1472,7 +1482,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_FLOAT:
case FILE_BEFLOAT:
case FILE_LEFLOAT:
- v = (int32_t) v;
+ v = CAST(int32_t, v);
break;
case FILE_QUAD:
case FILE_BEQUAD:
@@ -1489,7 +1499,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_DOUBLE:
case FILE_BEDOUBLE:
case FILE_LEDOUBLE:
- v = (int64_t) v;
+ v = CAST(int64_t, v);
break;
case FILE_STRING:
case FILE_PSTRING:
@@ -1616,7 +1626,7 @@ get_cond(const char *l, const char **t)
for (p = cond_tbl; p->len; p++) {
if (strncmp(l, p->name, p->len) == 0 &&
- isspace((unsigned char)l[p->len])) {
+ isspace(CAST(unsigned char, l[p->len]))) {
if (t)
*t = l + p->len;
break;
@@ -1674,7 +1684,7 @@ parse_indirect_modifier(struct magic_set *ms, struct magic *m, const char **lp)
{
const char *l = *lp;
- while (!isspace((unsigned char)*++l))
+ while (!isspace(CAST(unsigned char, *++l)))
switch (*l) {
case CHAR_INDIRECT_RELATIVE:
m->str_flags |= INDIRECT_RELATIVE;
@@ -1700,7 +1710,7 @@ parse_op_modifier(struct magic_set *ms, struct magic *m, const char **lp,
++l;
m->mask_op |= op;
- val = (uint64_t)strtoull(l, &t, 0);
+ val = CAST(uint64_t, strtoull(l, &t, 0));
l = t;
m->num_mask = file_signextend(ms, m, val);
eatsize(&l);
@@ -1714,7 +1724,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
char *t;
int have_range = 0;
- while (!isspace((unsigned char)*++l)) {
+ while (!isspace(CAST(unsigned char, *++l))) {
switch (*l) {
case '0': case '1': case '2':
case '3': case '4': case '5':
@@ -1796,7 +1806,7 @@ parse_string_modifier(struct magic_set *ms, struct magic *m, const char **lp)
goto out;
}
/* allow multiple '/' for readability */
- if (l[1] == '/' && !isspace((unsigned char)l[2]))
+ if (l[1] == '/' && !isspace(CAST(unsigned char, l[2])))
l++;
}
if (string_modifier_check(ms, m) == -1)
@@ -1833,7 +1843,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
*/
while (*l == '>') {
++l; /* step over */
- cont_level++;
+ cont_level++;
}
#ifdef ENABLE_CONDITIONALS
if (cont_level == 0 || cont_level > last_cont_level)
@@ -1851,7 +1861,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
return -1;
}
m = &me->mp[me->cont_count - 1];
- diff = (int32_t)cont_level - (int32_t)m->cont_level;
+ diff = CAST(int32_t, cont_level) - CAST(int32_t, m->cont_level);
if (diff > 1)
file_magwarn(ms, "New continuation level %u is more "
"than one larger than current level %u", cont_level,
@@ -1864,7 +1874,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
file_oomem(ms, sizeof(*nm) * cnt);
return -1;
}
- me->mp = m = nm;
+ me->mp = nm;
me->max_count = CAST(uint32_t, cnt);
}
m = &me->mp[me->cont_count++];
@@ -1910,7 +1920,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
}
/* get offset, then skip over it */
- m->offset = (int32_t)strtol(l, &t, 0);
+ m->offset = CAST(int32_t, strtol(l, &t, 0));
if (l == t) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "offset `%s' invalid", l);
@@ -2008,8 +2018,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
m->in_op |= FILE_OPINDIRECT;
l++;
}
- if (isdigit((unsigned char)*l) || *l == '-') {
- m->in_offset = (int32_t)strtol(l, &t, 0);
+ if (isdigit(CAST(unsigned char, *l)) || *l == '-') {
+ m->in_offset = CAST(int32_t, strtol(l, &t, 0));
if (l == t) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
@@ -2018,7 +2028,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
}
l = t;
}
- if (*l++ != ')' ||
+ if (*l++ != ')' ||
((m->in_op & FILE_OPINDIRECT) && *l++ != ')')) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms,
@@ -2043,7 +2053,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
/*
* Try it as a keyword type prefixed by "u"; match what
* follows the "u". If that fails, try it as an SUS
- * integer type.
+ * integer type.
*/
m->type = get_type(type_tbl, l + 1, &l);
if (m->type == FILE_INVALID) {
@@ -2072,7 +2082,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
*/
if (*l == 'd')
m->type = get_standard_integer_type(l, &l);
- else if (*l == 's' && !isalpha((unsigned char)l[1])) {
+ else if (*l == 's'
+ && !isalpha(CAST(unsigned char, l[1]))) {
m->type = FILE_STRING;
++l;
}
@@ -2083,7 +2094,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
/* Not found - try it as a special keyword. */
m->type = get_type(special_tbl, l, &l);
}
-
+
if (m->type == FILE_INVALID) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "type `%s' invalid", l);
@@ -2130,7 +2141,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
* anything if mask = 0 (unless you have a better idea)
*/
EATAB;
-
+
switch (*l) {
case '>':
case '<':
@@ -2162,8 +2173,8 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
break;
default:
m->reln = '='; /* the default relation */
- if (*l == 'x' && ((isascii((unsigned char)l[1]) &&
- isspace((unsigned char)l[1])) || !l[1])) {
+ if (*l == 'x' && ((isascii(CAST(unsigned char, l[1])) &&
+ isspace(CAST(unsigned char, l[1]))) || !l[1])) {
m->reln = *l;
++l;
}
@@ -2177,7 +2188,7 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
/*
* TODO finish this macro and start using it!
- * #define offsetcheck {if (offset > ms->bytes_max -1)
+ * #define offsetcheck {if (offset > ms->bytes_max -1)
* magwarn("offset too big"); }
*/
@@ -2260,11 +2271,11 @@ parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
file_magwarn(ms, "Too large factor `%lu'", factor);
goto out;
}
- if (*el && !isspace((unsigned char)*el)) {
+ if (*el && !isspace(CAST(unsigned char, *el))) {
file_magwarn(ms, "Bad factor `%s'", l);
goto out;
}
- m->factor = (uint8_t)factor;
+ m->factor = CAST(uint8_t, factor);
if (m->factor == 0 && m->factor_op == FILE_FACTOR_OP_DIV) {
file_magwarn(ms, "Cannot have factor op `%c' and factor %u",
m->factor_op, m->factor);
@@ -2295,9 +2306,9 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
if (buf[0] != '\0') {
len = nt ? strlen(buf) : len;
file_magwarn(ms, "Current entry already has a %s type "
- "`%.*s', new type `%s'", name, (int)len, buf, l);
+ "`%.*s', new type `%s'", name, CAST(int, len), buf, l);
return -1;
- }
+ }
if (*m->desc == '\0') {
file_magwarn(ms, "Current entry does not yet have a "
@@ -2316,7 +2327,7 @@ parse_extra(struct magic_set *ms, struct magic_entry *me, const char *line,
file_magwarn(ms, "%s type `%s' truncated %"
SIZE_T_FORMAT "u", name, line, i);
} else {
- if (!isspace((unsigned char)*l) && !goodchar(*l, extra))
+ if (!isspace(CAST(unsigned char, *l)) && !goodchar(*l, extra))
file_magwarn(ms, "%s type `%s' has bad char '%c'",
name, line, *l);
if (nt)
@@ -2418,7 +2429,7 @@ check_format_type(const char *ptr, int type, const char **estr)
if (*ptr == '#')
ptr++;
#define CHECKLEN() do { \
- for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \
+ for (len = cnt = 0; isdigit(CAST(unsigned char, *ptr)); ptr++, cnt++) \
len = len * 10 + (*ptr - '0'); \
if (cnt > 5 || len > 1024) \
goto toolong; \
@@ -2434,7 +2445,7 @@ check_format_type(const char *ptr, int type, const char **estr)
if (*ptr++ != 'l')
goto invalid;
}
-
+
switch (*ptr++) {
#ifdef STRICT_FORMAT /* "long" formats are int formats for us */
/* so don't accept the 'l' modifier */
@@ -2452,7 +2463,7 @@ check_format_type(const char *ptr, int type, const char **estr)
default:
goto invalid;
}
-
+
/*
* Don't accept h and hh modifiers. They make writing
* magic entries more complicated, for very little benefit
@@ -2508,7 +2519,7 @@ check_format_type(const char *ptr, int type, const char **estr)
default:
goto invalid;
}
-
+
case FILE_FMT_FLOAT:
case FILE_FMT_DOUBLE:
if (*ptr == '-')
@@ -2527,30 +2538,30 @@ check_format_type(const char *ptr, int type, const char **estr)
case 'g':
case 'G':
return 0;
-
+
default:
goto invalid;
}
-
+
case FILE_FMT_STR:
if (*ptr == '-')
ptr++;
- while (isdigit((unsigned char )*ptr))
+ while (isdigit(CAST(unsigned char, *ptr)))
ptr++;
if (*ptr == '.') {
ptr++;
- while (isdigit((unsigned char )*ptr))
+ while (isdigit(CAST(unsigned char , *ptr)))
ptr++;
}
-
+
switch (*ptr++) {
case 's':
return 0;
default:
goto invalid;
}
-
+
default:
/* internal error */
abort();
@@ -2561,7 +2572,7 @@ check_format_type(const char *ptr, int type, const char **estr)
*estr = "too long";
return -1;
}
-
+
/*
* Check that the optional printf format in description matches
* the type of the magic.
@@ -2584,7 +2595,7 @@ check_format(struct magic_set *ms, struct magic *m)
if (m->type >= file_nformats) {
file_magwarn(ms, "Internal error inconsistency between "
- "m->type and format strings");
+ "m->type and format strings");
return -1;
}
if (file_formats[m->type] == FILE_FMT_NONE) {
@@ -2604,7 +2615,7 @@ check_format(struct magic_set *ms, struct magic *m)
file_names[m->type], m->desc);
return -1;
}
-
+
for (; *ptr; ptr++) {
if (*ptr == '%') {
file_magwarn(ms,
@@ -2617,9 +2628,9 @@ check_format(struct magic_set *ms, struct magic *m)
return 0;
}
-/*
- * Read a numeric value from a pointer, into the value union of a magic
- * pointer, according to the magic type. Update the string pointer to point
+/*
+ * Read a numeric value from a pointer, into the value union of a magic
+ * pointer, according to the magic type. Update the string pointer to point
* just after the number read. Return 0 for success, non-zero for failure.
*/
private int
@@ -2685,7 +2696,7 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
return 0;
default:
errno = 0;
- ull = (uint64_t)strtoull(*p, &ep, 0);
+ ull = CAST(uint64_t, strtoull(*p, &ep, 0));
m->value.q = file_signextend(ms, m, ull);
if (*p == ep) {
file_magwarn(ms, "Unparseable number `%s'", *p);
@@ -2694,24 +2705,24 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action)
uint64_t x;
const char *q;
- if (ts == (size_t)~0) {
+ if (ts == CAST(size_t, ~0)) {
file_magwarn(ms,
"Expected numeric type got `%s'",
type_tbl[m->type].name);
}
- for (q = *p; isspace((unsigned char)*q); q++)
+ for (q = *p; isspace(CAST(unsigned char, *q)); q++)
continue;
if (*q == '-')
- ull = -(int64_t)ull;
+ ull = -CAST(int64_t, ull);
switch (ts) {
case 1:
- x = (uint64_t)(ull & ~0xffULL);
+ x = CAST(uint64_t, ull & ~0xffULL);
break;
case 2:
- x = (uint64_t)(ull & ~0xffffULL);
+ x = CAST(uint64_t, ull & ~0xffffULL);
break;
case 4:
- x = (uint64_t)(ull & ~0xffffffffULL);
+ x = CAST(uint64_t, ull & ~0xffffffffULL);
break;
case 8:
x = 0;
@@ -2751,7 +2762,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
int val;
while ((c = *s++) != '\0') {
- if (isspace((unsigned char) c))
+ if (isspace(CAST(unsigned char, c)))
break;
if (p >= pmax) {
file_error(ms, 0, "string too long: `%s'", origs);
@@ -2775,8 +2786,8 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
/*FALLTHROUGH*/
default:
if (warn) {
- if (isprint((unsigned char)c)) {
- /* Allow escaping of
+ if (isprint(CAST(unsigned char, c))) {
+ /* Allow escaping of
* ``relations'' */
if (strchr("<>&^=!", c) == NULL
&& (m->type != FILE_REGEX ||
@@ -2813,7 +2824,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
case '!':
/* and baskslash itself */
case '\\':
- *p++ = (char) c;
+ *p++ = CAST(char, c);
break;
case 'a':
@@ -2865,7 +2876,7 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
}
else
--s;
- *p++ = (char)val;
+ *p++ = CAST(char, val);
break;
/* \x and up to 2 hex digits */
@@ -2881,18 +2892,18 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
--s;
} else
--s;
- *p++ = (char)val;
+ *p++ = CAST(char, val);
break;
}
} else
- *p++ = (char)c;
+ *p++ = CAST(char, c);
}
--s;
out:
*p = '\0';
m->vallen = CAST(unsigned char, (p - origp));
if (m->type == FILE_PSTRING)
- m->vallen += (unsigned char)file_pstring_length_size(m);
+ m->vallen += CAST(unsigned char, file_pstring_length_size(m));
return s;
}
@@ -2901,9 +2912,9 @@ getstr(struct magic_set *ms, struct magic *m, const char *s, int warn)
private int
hextoint(int c)
{
- if (!isascii((unsigned char) c))
+ if (!isascii(CAST(unsigned char, c)))
return -1;
- if (isdigit((unsigned char) c))
+ if (isdigit(CAST(unsigned char, c)))
return c - '0';
if ((c >= 'a') && (c <= 'f'))
return c + 10 - 'a';
@@ -2981,7 +2992,7 @@ eatsize(const char **p)
{
const char *l = *p;
- if (LOWCASE(*l) == 'u')
+ if (LOWCASE(*l) == 'u')
l++;
switch (LOWCASE(*l)) {
@@ -3052,17 +3063,17 @@ apprentice_map(struct magic_set *ms, const char *fn)
file_error(ms, errno, "cannot stat `%s'", dbname);
goto error;
}
- if (st.st_size < 8 || st.st_size > MAXMAGIC_SIZE) {
+ if (st.st_size < 8 || st.st_size > maxoff_t()) {
file_error(ms, 0, "file `%s' is too %s", dbname,
st.st_size < 8 ? "small" : "large");
goto error;
}
- map->len = (size_t)st.st_size;
+ map->len = CAST(size_t, st.st_size);
#ifdef QUICK
map->type = MAP_TYPE_MMAP;
- if ((map->p = mmap(0, (size_t)st.st_size, PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_FILE, fd, (off_t)0)) == MAP_FAILED) {
+ if ((map->p = mmap(0, CAST(size_t, st.st_size), PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_FILE, fd, CAST(off_t, 0))) == MAP_FAILED) {
file_error(ms, errno, "cannot map `%s'", dbname);
goto error;
}
@@ -3082,11 +3093,11 @@ apprentice_map(struct magic_set *ms, const char *fn)
fd = -1;
if (check_buffer(ms, map, dbname) != 0) {
- rv = (struct magic_map *)-1;
+ rv = RCAST(struct magic_map *, -1);
goto error;
}
#ifdef QUICK
- if (mprotect(map->p, (size_t)st.st_size, PROT_READ) == -1) {
+ if (mprotect(map->p, CAST(size_t, st.st_size), PROT_READ) == -1) {
file_error(ms, errno, "cannot mprotect `%s'", dbname);
goto error;
}
@@ -3130,7 +3141,7 @@ check_buffer(struct magic_set *ms, struct magic_map *map, const char *dbname)
VERSIONNO, dbname, version);
return -1;
}
- entries = (uint32_t)(map->len / sizeof(struct magic));
+ entries = CAST(uint32_t, map->len / sizeof(struct magic));
if ((entries * sizeof(struct magic)) != map->len) {
file_error(ms, 0, "Size of `%s' %" SIZE_T_FORMAT "u is not "
"a multiple of %" SIZE_T_FORMAT "u",
@@ -3179,10 +3190,10 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
dbname = mkdbname(ms, fn, 1);
- if (dbname == NULL)
+ if (dbname == NULL)
goto out;
- if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
+ if ((fd = open(dbname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644)) == -1)
{
file_error(ms, errno, "cannot open `%s'", dbname);
goto out;
@@ -3192,14 +3203,14 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
hdr.h[1] = VERSIONNO;
memcpy(hdr.h + 2, map->nmagic, nm);
- if (write(fd, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr)) {
+ if (write(fd, &hdr, sizeof(hdr)) != CAST(ssize_t, sizeof(hdr))) {
file_error(ms, errno, "error writing `%s'", dbname);
goto out2;
}
for (i = 0; i < MAGIC_SETS; i++) {
len = m * map->nmagic[i];
- if (write(fd, map->magic[i], len) != (ssize_t)len) {
+ if (write(fd, map->magic[i], len) != CAST(ssize_t, len)) {
file_error(ms, errno, "error writing `%s'", dbname);
goto out2;
}
@@ -3245,7 +3256,8 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
q++;
/* Compatibility with old code that looked in .mime */
if (ms->flags & MAGIC_MIME) {
- if (asprintf(&buf, "%.*s.mime%s", (int)(q - fn), fn, ext) < 0)
+ if (asprintf(&buf, "%.*s.mime%s", CAST(int, q - fn), fn, ext)
+ < 0)
return NULL;
if (access(buf, R_OK) != -1) {
ms->flags &= MAGIC_MIME_TYPE;
@@ -3253,7 +3265,7 @@ mkdbname(struct magic_set *ms, const char *fn, int strip)
}
free(buf);
}
- if (asprintf(&buf, "%.*s%s", (int)(q - fn), fn, ext) < 0)
+ if (asprintf(&buf, "%.*s%s", CAST(int, q - fn), fn, ext) < 0)
return NULL;
/* Compatibility with old code that looked in .mime */
@@ -3280,8 +3292,8 @@ private uint16_t
swap2(uint16_t sv)
{
uint16_t rv;
- uint8_t *s = (uint8_t *)(void *)&sv;
- uint8_t *d = (uint8_t *)(void *)&rv;
+ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[1];
d[1] = s[0];
return rv;
@@ -3294,8 +3306,8 @@ private uint32_t
swap4(uint32_t sv)
{
uint32_t rv;
- uint8_t *s = (uint8_t *)(void *)&sv;
- uint8_t *d = (uint8_t *)(void *)&rv;
+ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
@@ -3310,8 +3322,8 @@ private uint64_t
swap8(uint64_t sv)
{
uint64_t rv;
- uint8_t *s = (uint8_t *)(void *)&sv;
- uint8_t *d = (uint8_t *)(void *)&rv;
+ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
#if 0
d[0] = s[3];
d[1] = s[2];
@@ -3341,9 +3353,9 @@ private void
bs1(struct magic *m)
{
m->cont_level = swap2(m->cont_level);
- m->offset = swap4((uint32_t)m->offset);
- m->in_offset = swap4((uint32_t)m->in_offset);
- m->lineno = swap4((uint32_t)m->lineno);
+ m->offset = swap4(CAST(uint32_t, m->offset));
+ m->in_offset = swap4(CAST(uint32_t, m->in_offset));
+ m->lineno = swap4(CAST(uint32_t, m->lineno));
if (IS_STRING(m->type)) {
m->str_range = swap4(m->str_range);
m->str_flags = swap4(m->str_flags);
@@ -3354,7 +3366,7 @@ bs1(struct magic *m)
}
}
-protected size_t
+protected size_t
file_pstring_length_size(const struct magic *m)
{
switch (m->str_flags & PSTRING_LEN) {
@@ -3375,7 +3387,7 @@ protected size_t
file_pstring_get_length(const struct magic *m, const char *ss)
{
size_t len = 0;
- const unsigned char *s = (const unsigned char *)ss;
+ const unsigned char *s = RCAST(const unsigned char *, ss);
unsigned int s3, s2, s1, s0;
switch (m->str_flags & PSTRING_LEN) {
diff --git a/libmagic/src/main/cpp/file/apptype.c b/libmagic/src/main/cpp/file/apptype.c
index 164c4f3..1bb33e4 100644
--- a/libmagic/src/main/cpp/file/apptype.c
+++ b/libmagic/src/main/cpp/file/apptype.c
@@ -1,15 +1,15 @@
/*
* Adapted from: apptype.c, Written by Eberhard Mattes and put into the
* public domain
- *
+ *
* Notes: 1. Qualify the filename so that DosQueryAppType does not do extraneous
* searches.
- *
+ *
* 2. DosQueryAppType will return FAPPTYP_DOS on a file ending with ".com"
* (other than an OS/2 exe or Win exe with this name). Eberhard Mattes
* remarks Tue, 6 Apr 93: Moreover, it reports the type of the (new and very
* bug ridden) Win Emacs as "OS/2 executable".
- *
+ *
* 3. apptype() uses the filename if given, otherwise a tmp file is created with
* the contents of buf. If buf is not the complete file, apptype can
* incorrectly identify the exe type. The "-z" option of "file" is the reason
@@ -18,16 +18,16 @@
/*
* amai: Darrel Hankerson did the changes described here.
- *
+ *
* It remains to check the validity of comments (2.) since it's referred to an
* "old" OS/2 version.
- *
+ *
*/
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apptype.c,v 1.12 2011/08/28 07:03:27 christos Exp $")
+FILE_RCSID("@(#)$File: apptype.c,v 1.14 2018/09/09 20:33:28 christos Exp $")
#endif /* lint */
#include
diff --git a/libmagic/src/main/cpp/file/ascmagic.c b/libmagic/src/main/cpp/file/ascmagic.c
index 2d1abe5..bcebeab 100644
--- a/libmagic/src/main/cpp/file/ascmagic.c
+++ b/libmagic/src/main/cpp/file/ascmagic.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: ascmagic.c,v 1.98 2017/11/02 20:25:39 christos Exp $")
+FILE_RCSID("@(#)$File: ascmagic.c,v 1.102 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -80,7 +80,13 @@ file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
const char *type = NULL;
bb = *b;
- bb.flen = trim_nuls(b->fbuf, b->flen);
+ bb.flen = trim_nuls(CAST(const unsigned char *, b->fbuf), b->flen);
+ /*
+ * Avoid trimming at an odd byte if the original buffer was evenly
+ * sized; this avoids losing the last character on UTF-16 LE text
+ */
+ if ((bb.flen & 1) && !(b->flen & 1))
+ bb.flen++;
/* If file doesn't look like any sort of text, give up. */
if (file_encoding(ms, &bb, &ubuf, &ulen, &code, &code_mime,
@@ -96,12 +102,12 @@ file_ascmagic(struct magic_set *ms, const struct buffer *b, int text)
}
protected int
-file_ascmagic_with_encoding(struct magic_set *ms,
+file_ascmagic_with_encoding(struct magic_set *ms,
const struct buffer *b, unichar *ubuf, size_t ulen, const char *code,
const char *type, int text)
{
struct buffer bb;
- const unsigned char *buf = b->fbuf;
+ const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
unsigned char *utf8_buf = NULL, *utf8_end;
size_t mlen, i;
@@ -121,7 +127,7 @@ file_ascmagic_with_encoding(struct magic_set *ms,
int n_nel = 0;
int executable = 0;
- size_t last_line_end = (size_t)-1;
+ size_t last_line_end = CAST(size_t, -1);
int has_long_lines = 0;
nbytes = trim_nuls(buf, nbytes);
@@ -145,7 +151,7 @@ file_ascmagic_with_encoding(struct magic_set *ms,
== NULL)
goto done;
buffer_init(&bb, b->fd, utf8_buf,
- (size_t)(utf8_end - utf8_buf));
+ CAST(size_t, utf8_end - utf8_buf));
if ((rv = file_softmagic(ms, &bb, NULL, NULL,
TEXTTEST, text)) == 0)
@@ -324,42 +330,42 @@ encode_utf8(unsigned char *buf, size_t len, unichar *ubuf, size_t ulen)
if (ubuf[i] <= 0x7f) {
if (end - buf < 1)
return NULL;
- *buf++ = (unsigned char)ubuf[i];
+ *buf++ = CAST(unsigned char, ubuf[i]);
} else if (ubuf[i] <= 0x7ff) {
if (end - buf < 2)
return NULL;
- *buf++ = (unsigned char)((ubuf[i] >> 6) + 0xc0);
- *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] >> 6) + 0xc0);
+ *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0xffff) {
if (end - buf < 3)
return NULL;
- *buf++ = (unsigned char)((ubuf[i] >> 12) + 0xe0);
- *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
- *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] >> 12) + 0xe0);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0x1fffff) {
if (end - buf < 4)
return NULL;
- *buf++ = (unsigned char)((ubuf[i] >> 18) + 0xf0);
- *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
- *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
- *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] >> 18) + 0xf0);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0x3ffffff) {
if (end - buf < 5)
return NULL;
- *buf++ = (unsigned char)((ubuf[i] >> 24) + 0xf8);
- *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
- *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
- *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
- *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] >> 24) + 0xf8);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else if (ubuf[i] <= 0x7fffffff) {
if (end - buf < 6)
return NULL;
- *buf++ = (unsigned char)((ubuf[i] >> 30) + 0xfc);
- *buf++ = (unsigned char)(((ubuf[i] >> 24) & 0x3f) + 0x80);
- *buf++ = (unsigned char)(((ubuf[i] >> 18) & 0x3f) + 0x80);
- *buf++ = (unsigned char)(((ubuf[i] >> 12) & 0x3f) + 0x80);
- *buf++ = (unsigned char)(((ubuf[i] >> 6) & 0x3f) + 0x80);
- *buf++ = (unsigned char)((ubuf[i] & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] >> 30) + 0xfc);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 24) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 18) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 12) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, ((ubuf[i] >> 6) & 0x3f) + 0x80);
+ *buf++ = CAST(unsigned char, (ubuf[i] & 0x3f) + 0x80);
} else /* Invalid character */
return NULL;
}
diff --git a/libmagic/src/main/cpp/file/asprintf.c b/libmagic/src/main/cpp/file/asprintf.c
index b065380..2d14e80 100644
--- a/libmagic/src/main/cpp/file/asprintf.c
+++ b/libmagic/src/main/cpp/file/asprintf.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 THE AUTHOR AND 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
@@ -29,7 +29,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: asprintf.c,v 1.3 2009/02/03 20:27:51 christos Exp $")
+FILE_RCSID("@(#)$File: asprintf.c,v 1.5 2018/09/09 20:33:28 christos Exp $")
#endif
int asprintf(char **ptr, const char *fmt, ...)
diff --git a/libmagic/src/main/cpp/file/buffer.c b/libmagic/src/main/cpp/file/buffer.c
index 5f76b80..fd40416 100644
--- a/libmagic/src/main/cpp/file/buffer.c
+++ b/libmagic/src/main/cpp/file/buffer.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: buffer.c,v 1.4 2018/02/21 21:26:00 christos Exp $")
+FILE_RCSID("@(#)$File: buffer.c,v 1.5 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -61,13 +61,13 @@ buffer_fill(const struct buffer *bb)
struct buffer *b = CCAST(struct buffer *, bb);
if (b->elen != 0)
- return b->elen == (size_t)~0 ? -1 : 0;
+ return b->elen == CAST(size_t, ~0) ? -1 : 0;
if (!S_ISREG(b->st.st_mode))
goto out;
- b->elen = (size_t)b->st.st_size < b->flen ?
- (size_t)b->st.st_size : b->flen;
+ b->elen = CAST(size_t, b->st.st_size) < b->flen ?
+ CAST(size_t, b->st.st_size) : b->flen;
if ((b->ebuf = malloc(b->elen)) == NULL)
goto out;
@@ -79,6 +79,6 @@ buffer_fill(const struct buffer *bb)
return 0;
out:
- b->elen = (size_t)~0;
+ b->elen = CAST(size_t, ~0);
return -1;
}
diff --git a/libmagic/src/main/cpp/file/cdf.c b/libmagic/src/main/cpp/file/cdf.c
index aad68cd..556a3ff 100644
--- a/libmagic/src/main/cpp/file/cdf.c
+++ b/libmagic/src/main/cpp/file/cdf.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.110 2017/12/19 00:21:21 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.114 2019/02/20 02:35:27 christos Exp $")
#endif
#include
@@ -47,9 +47,7 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.110 2017/12/19 00:21:21 christos Exp $")
#include
#include
#include
-#ifdef HAVE_LIMITS_H
#include
-#endif
#ifndef EFTYPE
#define EFTYPE EINVAL
@@ -68,11 +66,14 @@ static union {
uint32_t u;
} cdf_bo;
-#define NEED_SWAP (cdf_bo.u == (uint32_t)0x01020304)
+#define NEED_SWAP (cdf_bo.u == CAST(uint32_t, 0x01020304))
-#define CDF_TOLE8(x) ((uint64_t)(NEED_SWAP ? _cdf_tole8(x) : (uint64_t)(x)))
-#define CDF_TOLE4(x) ((uint32_t)(NEED_SWAP ? _cdf_tole4(x) : (uint32_t)(x)))
-#define CDF_TOLE2(x) ((uint16_t)(NEED_SWAP ? _cdf_tole2(x) : (uint16_t)(x)))
+#define CDF_TOLE8(x) \
+ (CAST(uint64_t, NEED_SWAP ? _cdf_tole8(x) : CAST(uint64_t, x)))
+#define CDF_TOLE4(x) \
+ (CAST(uint32_t, NEED_SWAP ? _cdf_tole4(x) : CAST(uint32_t, x)))
+#define CDF_TOLE2(x) \
+ (CAST(uint16_t, NEED_SWAP ? _cdf_tole2(x) : CAST(uint16_t, x)))
#define CDF_TOLE(x) (/*CONSTCOND*/sizeof(x) == 2 ? \
CDF_TOLE2(CAST(uint16_t, x)) : \
(/*CONSTCOND*/sizeof(x) == 4 ? \
@@ -90,7 +91,8 @@ static void *
cdf_malloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), size_t n)
{
- DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
+ DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
+ file, line, __func__, n));
return malloc(n);
}
@@ -99,7 +101,8 @@ static void *
cdf_realloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), void *p, size_t n)
{
- DPRINTF(("%s,%zu: %s %zu\n", file, line, __func__, n));
+ DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
+ file, line, __func__, n));
return realloc(p, n);
}
@@ -108,7 +111,8 @@ static void *
cdf_calloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), size_t n, size_t u)
{
- DPRINTF(("%s,%zu: %s %zu %zu\n", file, line, __func__, n, u));
+ DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u %"
+ SIZE_T_FORMAT "u\n", file, line, __func__, n, u));
return calloc(n, u);
}
@@ -119,8 +123,8 @@ static uint16_t
_cdf_tole2(uint16_t sv)
{
uint16_t rv;
- uint8_t *s = (uint8_t *)(void *)&sv;
- uint8_t *d = (uint8_t *)(void *)&rv;
+ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[1];
d[1] = s[0];
return rv;
@@ -133,8 +137,8 @@ static uint32_t
_cdf_tole4(uint32_t sv)
{
uint32_t rv;
- uint8_t *s = (uint8_t *)(void *)&sv;
- uint8_t *d = (uint8_t *)(void *)&rv;
+ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
@@ -149,8 +153,8 @@ static uint64_t
_cdf_tole8(uint64_t sv)
{
uint64_t rv;
- uint8_t *s = (uint8_t *)(void *)&sv;
- uint8_t *d = (uint8_t *)(void *)&rv;
+ uint8_t *s = RCAST(uint8_t *, RCAST(void *, &sv));
+ uint8_t *d = RCAST(uint8_t *, RCAST(void *, &rv));
d[0] = s[7];
d[1] = s[6];
d[2] = s[5];
@@ -215,15 +219,17 @@ cdf_swap_header(cdf_header_t *h)
h->h_min_size_standard_stream =
CDF_TOLE4(h->h_min_size_standard_stream);
h->h_secid_first_sector_in_short_sat =
- CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_short_sat);
+ CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_short_sat));
h->h_num_sectors_in_short_sat =
CDF_TOLE4(h->h_num_sectors_in_short_sat);
h->h_secid_first_sector_in_master_sat =
- CDF_TOLE4((uint32_t)h->h_secid_first_sector_in_master_sat);
+ CDF_TOLE4(CAST(uint32_t, h->h_secid_first_sector_in_master_sat));
h->h_num_sectors_in_master_sat =
CDF_TOLE4(h->h_num_sectors_in_master_sat);
- for (i = 0; i < __arraycount(h->h_master_sat); i++)
- h->h_master_sat[i] = CDF_TOLE4((uint32_t)h->h_master_sat[i]);
+ for (i = 0; i < __arraycount(h->h_master_sat); i++) {
+ h->h_master_sat[i] =
+ CDF_TOLE4(CAST(uint32_t, h->h_master_sat[i]));
+ }
}
void
@@ -256,15 +262,16 @@ void
cdf_swap_dir(cdf_directory_t *d)
{
d->d_namelen = CDF_TOLE2(d->d_namelen);
- d->d_left_child = CDF_TOLE4((uint32_t)d->d_left_child);
- d->d_right_child = CDF_TOLE4((uint32_t)d->d_right_child);
- d->d_storage = CDF_TOLE4((uint32_t)d->d_storage);
+ d->d_left_child = CDF_TOLE4(CAST(uint32_t, d->d_left_child));
+ d->d_right_child = CDF_TOLE4(CAST(uint32_t, d->d_right_child));
+ d->d_storage = CDF_TOLE4(CAST(uint32_t, d->d_storage));
d->d_storage_uuid[0] = CDF_TOLE8(d->d_storage_uuid[0]);
d->d_storage_uuid[1] = CDF_TOLE8(d->d_storage_uuid[1]);
d->d_flags = CDF_TOLE4(d->d_flags);
- d->d_created = CDF_TOLE8((uint64_t)d->d_created);
- d->d_modified = CDF_TOLE8((uint64_t)d->d_modified);
- d->d_stream_first_sector = CDF_TOLE4((uint32_t)d->d_stream_first_sector);
+ d->d_created = CDF_TOLE8(CAST(uint64_t, d->d_created));
+ d->d_modified = CDF_TOLE8(CAST(uint64_t, d->d_modified));
+ d->d_stream_first_sector = CDF_TOLE4(
+ CAST(uint32_t, d->d_stream_first_sector));
d->d_size = CDF_TOLE4(d->d_size);
}
@@ -321,11 +328,11 @@ static int
cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
const void *p, size_t tail, int line)
{
- const char *b = (const char *)sst->sst_tab;
- const char *e = ((const char *)p) + tail;
+ const char *b = RCAST(const char *, sst->sst_tab);
+ const char *e = RCAST(const char *, p) + tail;
size_t ss = cdf_check_stream(sst, h);
/*LINTED*/(void)&line;
- if (e >= b && (size_t)(e - b) <= ss * sst->sst_len)
+ if (e >= b && CAST(size_t, e - b) <= ss * sst->sst_len)
return 0;
DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u"
" > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %"
@@ -338,23 +345,23 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
static ssize_t
cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len)
{
- size_t siz = (size_t)off + len;
+ size_t siz = CAST(size_t, off + len);
- if ((off_t)(off + len) != (off_t)siz)
+ if (CAST(off_t, off + len) != CAST(off_t, siz))
goto out;
if (info->i_buf != NULL && info->i_len >= siz) {
(void)memcpy(buf, &info->i_buf[off], len);
- return (ssize_t)len;
+ return CAST(ssize_t, len);
}
if (info->i_fd == -1)
goto out;
- if (pread(info->i_fd, buf, len, off) != (ssize_t)len)
+ if (pread(info->i_fd, buf, len, off) != CAST(ssize_t, len))
return -1;
- return (ssize_t)len;
+ return CAST(ssize_t, len);
out:
errno = EINVAL;
return -1;
@@ -366,7 +373,7 @@ cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
char buf[512];
(void)memcpy(cdf_bo.s, "\01\02\03\04", 4);
- if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1)
+ if (cdf_read(info, CAST(off_t, 0), buf, sizeof(buf)) == -1)
return -1;
cdf_unpack_header(h, buf);
cdf_swap_header(h);
@@ -400,7 +407,7 @@ cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len,
size_t ss = CDF_SEC_SIZE(h);
size_t pos = CDF_SEC_POS(h, id);
assert(ss == len);
- return cdf_read(info, (off_t)pos, ((char *)buf) + offs, len);
+ return cdf_read(info, CAST(off_t, pos), RCAST(char *, buf) + offs, len);
}
ssize_t
@@ -416,8 +423,8 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs,
pos + len, CDF_SEC_SIZE(h) * sst->sst_len));
goto out;
}
- (void)memcpy(((char *)buf) + offs,
- ((const char *)sst->sst_tab) + pos, len);
+ (void)memcpy(RCAST(char *, buf) + offs,
+ RCAST(const char *, sst->sst_tab) + pos, len);
return len;
out:
errno = EFTYPE;
@@ -460,7 +467,7 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
if (h->h_master_sat[i] < 0)
break;
if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
- h->h_master_sat[i]) != (ssize_t)ss) {
+ h->h_master_sat[i]) != CAST(ssize_t, ss)) {
DPRINTF(("Reading sector %d", h->h_master_sat[i]));
goto out1;
}
@@ -477,27 +484,29 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
DPRINTF(("Reading master sector loop limit"));
goto out3;
}
- if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) {
+ if (cdf_read_sector(info, msa, 0, ss, h, mid) !=
+ CAST(ssize_t, ss)) {
DPRINTF(("Reading master sector %d", mid));
goto out2;
}
for (k = 0; k < nsatpersec; k++, i++) {
- sec = CDF_TOLE4((uint32_t)msa[k]);
+ sec = CDF_TOLE4(CAST(uint32_t, msa[k]));
if (sec < 0)
goto out;
if (i >= sat->sat_len) {
- DPRINTF(("Out of bounds reading MSA %" SIZE_T_FORMAT
- "u >= %" SIZE_T_FORMAT "u", i, sat->sat_len));
+ DPRINTF(("Out of bounds reading MSA %"
+ SIZE_T_FORMAT "u >= %" SIZE_T_FORMAT "u",
+ i, sat->sat_len));
goto out3;
}
if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
- sec) != (ssize_t)ss) {
+ sec) != CAST(ssize_t, ss)) {
DPRINTF(("Reading sector %d",
CDF_TOLE4(msa[k])));
goto out2;
}
}
- mid = CDF_TOLE4((uint32_t)msa[nsatpersec]);
+ mid = CDF_TOLE4(CAST(uint32_t, msa[nsatpersec]));
}
out:
sat->sat_len = i;
@@ -516,7 +525,7 @@ size_t
cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
{
size_t i, j;
- cdf_secid_t maxsector = (cdf_secid_t)((sat->sat_len * size)
+ cdf_secid_t maxsector = CAST(cdf_secid_t, (sat->sat_len * size)
/ sizeof(maxsector));
DPRINTF(("Chain:"));
@@ -536,7 +545,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
DPRINTF(("Sector %d >= %d\n", sid, maxsector));
goto out;
}
- sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+ sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
if (i == 0) {
DPRINTF((" none, sid: %d\n", sid));
@@ -547,7 +556,7 @@ cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size)
return i;
out:
errno = EFTYPE;
- return (size_t)-1;
+ return CAST(size_t, -1);
}
int
@@ -564,7 +573,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
if (sid == CDF_SECID_END_OF_CHAIN || len == 0)
return cdf_zero_stream(scn);
- if (scn->sst_len == (size_t)-1)
+ if (scn->sst_len == CAST(size_t, -1))
goto out;
scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
@@ -583,7 +592,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
goto out;
}
if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
- sid)) != (ssize_t)ss) {
+ sid)) != CAST(ssize_t, ss)) {
if (i == scn->sst_len - 1 && nr > 0) {
/* Last sector might be truncated */
return 0;
@@ -591,7 +600,7 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
DPRINTF(("Reading long sector chain %d", sid));
goto out;
}
- sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+ sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
return 0;
out:
@@ -610,7 +619,7 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
scn->sst_dirlen = len;
scn->sst_ss = ss;
- if (scn->sst_len == (size_t)-1)
+ if (scn->sst_len == CAST(size_t, -1))
goto out;
scn->sst_tab = CDF_CALLOC(scn->sst_len, ss);
@@ -629,11 +638,11 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
goto out;
}
if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
- sid) != (ssize_t)ss) {
+ sid) != CAST(ssize_t, ss)) {
DPRINTF(("Reading short sector chain %d", sid));
goto out;
}
- sid = CDF_TOLE4((uint32_t)ssat->sat_tab[sid]);
+ sid = CDF_TOLE4(CAST(uint32_t, ssat->sat_tab[sid]));
}
return 0;
out:
@@ -664,7 +673,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
cdf_secid_t sid = h->h_secid_first_directory;
ns = cdf_count_chain(sat, sid, ss);
- if (ns == (size_t)-1)
+ if (ns == CAST(size_t, -1))
return -1;
nd = ss / CDF_DIRECTORY_SIZE;
@@ -685,7 +694,8 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
DPRINTF(("Read dir loop limit"));
goto out;
}
- if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) {
+ if (cdf_read_sector(info, buf, 0, ss, h, sid) !=
+ CAST(ssize_t, ss)) {
DPRINTF(("Reading directory sector %d", sid));
goto out;
}
@@ -693,7 +703,7 @@ cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h,
cdf_unpack_dir(&dir->dir_tab[i * nd + j],
&buf[j * CDF_DIRECTORY_SIZE]);
}
- sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+ sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
if (NEED_SWAP)
for (i = 0; i < dir->dir_len; i++)
@@ -718,7 +728,7 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
ssat->sat_tab = NULL;
ssat->sat_len = cdf_count_chain(sat, sid, ss);
- if (ssat->sat_len == (size_t)-1)
+ if (ssat->sat_len == CAST(size_t, -1))
goto out;
ssat->sat_tab = CAST(cdf_secid_t *, CDF_CALLOC(ssat->sat_len, ss));
@@ -737,11 +747,11 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
goto out;
}
if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
- (ssize_t)ss) {
+ CAST(ssize_t, ss)) {
DPRINTF(("Reading short sat sector %d", sid));
goto out1;
}
- sid = CDF_TOLE4((uint32_t)sat->sat_tab[sid]);
+ sid = CDF_TOLE4(CAST(uint32_t, sat->sat_tab[sid]));
}
return 0;
out:
@@ -791,7 +801,7 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l)
{
for (; l--; d++, s++)
if (*d != CDF_TOLE2(*s))
- return (unsigned char)*d - CDF_TOLE2(*s);
+ return CAST(unsigned char, *d) - CDF_TOLE2(*s);
return 0;
}
@@ -859,7 +869,7 @@ cdf_offset(const void *p, size_t l)
}
static const uint8_t *
-cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
+cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
const uint8_t *p, const uint8_t *e, size_t i)
{
size_t tail = (i << 1) + 1;
@@ -874,7 +884,7 @@ cdf_get_property_info_pos(const cdf_stream_t *sst, const cdf_header_t *h,
__LINE__) == -1)
return NULL;
ofs = CDF_GETUINT32(p, tail);
- q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
+ q = CAST(const uint8_t *, cdf_offset(CAST(const void *, p),
ofs - 2 * sizeof(uint32_t)));
if (q < p) {
@@ -896,8 +906,8 @@ cdf_grow_info(cdf_property_info_t **info, size_t *maxcount, size_t incr)
size_t newcount = *maxcount + incr;
if (newcount > CDF_PROP_LIMIT) {
- DPRINTF(("exceeded property limit %zu > %zu\n",
- newcount, CDF_PROP_LIMIT));
+ DPRINTF(("exceeded property limit %" SIZE_T_FORMAT "u > %"
+ SIZE_T_FORMAT "u\n", newcount, CDF_PROP_LIMIT));
goto out;
}
inp = CAST(cdf_property_info_t *,
@@ -922,7 +932,7 @@ cdf_copy_info(cdf_property_info_t *inp, const void *p, const void *e,
if (inp->pi_type & CDF_VECTOR)
return 0;
- if ((size_t)(CAST(const char *, e) - CAST(const char *, p)) < len)
+ if (CAST(size_t, CAST(const char *, e) - CAST(const char *, p)) < len)
return 0;
(void)memcpy(&inp->pi_val, p, len);
@@ -1065,10 +1075,10 @@ cdf_read_property_info(const cdf_stream_t *sst, const cdf_header_t *h,
inp[i].pi_str.s_buf = CAST(const char *,
CAST(const void *, &q[o4]));
- DPRINTF(("o=%zu l=%d(%" SIZE_T_FORMAT
- "u), t=%zu s=%s\n", o4, l,
- CDF_ROUND(l, sizeof(l)), left,
- inp[i].pi_str.s_buf));
+ DPRINTF(("o=%" SIZE_T_FORMAT "u l=%d(%"
+ SIZE_T_FORMAT "u), t=%" SIZE_T_FORMAT
+ "u s=%s\n", o4, l, CDF_ROUND(l, sizeof(l)),
+ left, inp[i].pi_str.s_buf));
if (l & 1)
l++;
@@ -1108,8 +1118,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, const cdf_header_t *h,
const cdf_summary_info_header_t *si =
CAST(const cdf_summary_info_header_t *, sst->sst_tab);
const cdf_section_declaration_t *sd =
- CAST(const cdf_section_declaration_t *, (const void *)
- ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET));
+ CAST(const cdf_section_declaration_t *, RCAST(const void *,
+ RCAST(const char *, sst->sst_tab)
+ + CDF_SECTION_DECLARATION_OFFSET));
if (cdf_check_stream_offset(sst, h, si, sizeof(*si), __LINE__) == -1 ||
cdf_check_stream_offset(sst, h, sd, sizeof(*sd), __LINE__) == -1)
@@ -1260,28 +1271,28 @@ cdf_print_elapsed_time(char *buf, size_t bufsiz, cdf_timestamp_t ts)
int days, hours, mins, secs;
ts /= CDF_TIME_PREC;
- secs = (int)(ts % 60);
+ secs = CAST(int, ts % 60);
ts /= 60;
- mins = (int)(ts % 60);
+ mins = CAST(int, ts % 60);
ts /= 60;
- hours = (int)(ts % 24);
+ hours = CAST(int, ts % 24);
ts /= 24;
- days = (int)ts;
+ days = CAST(int, ts);
if (days) {
len += snprintf(buf + len, bufsiz - len, "%dd+", days);
- if ((size_t)len >= bufsiz)
+ if (CAST(size_t, len) >= bufsiz)
return len;
}
if (days || hours) {
len += snprintf(buf + len, bufsiz - len, "%.2d:", hours);
- if ((size_t)len >= bufsiz)
+ if (CAST(size_t, len) >= bufsiz)
return len;
}
len += snprintf(buf + len, bufsiz - len, "%.2d:", mins);
- if ((size_t)len >= bufsiz)
+ if (CAST(size_t, len) >= bufsiz)
return len;
len += snprintf(buf + len, bufsiz - len, "%.2d", secs);
@@ -1293,7 +1304,7 @@ cdf_u16tos8(char *buf, size_t len, const uint16_t *p)
{
size_t i;
for (i = 0; i < len && p[i]; i++)
- buf[i] = (char)p[i];
+ buf[i] = CAST(char, p[i]);
buf[i] = '\0';
return buf;
}
diff --git a/libmagic/src/main/cpp/file/cdf.h b/libmagic/src/main/cpp/file/cdf.h
index f2df830..2f7e554 100644
--- a/libmagic/src/main/cpp/file/cdf.h
+++ b/libmagic/src/main/cpp/file/cdf.h
@@ -76,9 +76,9 @@ typedef struct {
cdf_secid_t h_master_sat[436/4];
} cdf_header_t;
-#define CDF_SEC_SIZE(h) ((size_t)(1 << (h)->h_sec_size_p2))
+#define CDF_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_sec_size_p2)
#define CDF_SEC_POS(h, secid) (CDF_SEC_SIZE(h) + (secid) * CDF_SEC_SIZE(h))
-#define CDF_SHORT_SEC_SIZE(h) ((size_t)(1 << (h)->h_short_sec_size_p2))
+#define CDF_SHORT_SEC_SIZE(h) CAST(size_t, 1 << (h)->h_short_sec_size_p2)
#define CDF_SHORT_SEC_POS(h, secid) ((secid) * CDF_SHORT_SEC_SIZE(h))
typedef int32_t cdf_dirid_t;
@@ -272,7 +272,7 @@ typedef struct {
typedef struct {
uint16_t ce_namlen;
uint32_t ce_num;
- uint64_t ce_timestamp;
+ uint64_t ce_timestamp;
uint16_t ce_name[256];
} cdf_catalog_entry_t;
diff --git a/libmagic/src/main/cpp/file/cdf_time.c b/libmagic/src/main/cpp/file/cdf_time.c
index 2bdcd2a..bdb2d3a 100644
--- a/libmagic/src/main/cpp/file/cdf_time.c
+++ b/libmagic/src/main/cpp/file/cdf_time.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: cdf_time.c,v 1.16 2017/03/29 15:57:48 christos Exp $")
+FILE_RCSID("@(#)$File: cdf_time.c,v 1.18 2019/02/20 02:35:27 christos Exp $")
#endif
#include
@@ -56,7 +56,7 @@ cdf_getdays(int year)
for (y = CDF_BASE_YEAR; y < year; y++)
days += isleap(y) + 365;
-
+
return days;
}
@@ -77,7 +77,7 @@ cdf_getday(int year, int days)
return days;
}
-/*
+/*
* Return the 0...11 month number.
*/
static int
@@ -90,9 +90,9 @@ cdf_getmonth(int year, int days)
if (m == 1 && isleap(year))
days--;
if (days <= 0)
- return (int)m;
+ return CAST(int, m);
}
- return (int)m;
+ return CAST(int, m);
}
int
@@ -108,22 +108,22 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t)
ts->tv_nsec = (t % CDF_TIME_PREC) * 100;
t /= CDF_TIME_PREC;
- tm.tm_sec = (int)(t % 60);
+ tm.tm_sec = CAST(int, t % 60);
t /= 60;
- tm.tm_min = (int)(t % 60);
+ tm.tm_min = CAST(int, t % 60);
t /= 60;
- tm.tm_hour = (int)(t % 24);
+ tm.tm_hour = CAST(int, t % 24);
t /= 24;
/* XXX: Approx */
- tm.tm_year = (int)(CDF_BASE_YEAR + (t / 365));
+ tm.tm_year = CAST(int, CDF_BASE_YEAR + (t / 365));
rdays = cdf_getdays(tm.tm_year);
t -= rdays - 1;
- tm.tm_mday = cdf_getday(tm.tm_year, (int)t);
- tm.tm_mon = cdf_getmonth(tm.tm_year, (int)t);
+ tm.tm_mday = cdf_getday(tm.tm_year, CAST(int, t));
+ tm.tm_mon = cdf_getmonth(tm.tm_year, CAST(int, t));
tm.tm_wday = 0;
tm.tm_yday = 0;
tm.tm_isdst = 0;
@@ -172,7 +172,7 @@ cdf_ctime(const time_t *sec, char *buf)
if (ptr != NULL)
return buf;
(void)snprintf(buf, 26, "*Bad* %#16.16" INT64_T_FORMAT "x\n",
- (long long)*sec);
+ CAST(long long, *sec));
return buf;
}
diff --git a/libmagic/src/main/cpp/file/compress.c b/libmagic/src/main/cpp/file/compress.c
index 5d565d5..89fc570 100644
--- a/libmagic/src/main/cpp/file/compress.c
+++ b/libmagic/src/main/cpp/file/compress.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 THE AUTHOR AND 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
@@ -29,13 +29,13 @@
* compress routines:
* zmagic() - returns 0 if not recognized, uncompresses and prints
* information if recognized
- * uncompress(method, old, n, newch) - uncompress old into new,
+ * uncompress(method, old, n, newch) - uncompress old into new,
* using method, return sizeof new
*/
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: compress.c,v 1.107 2018/04/28 18:48:22 christos Exp $")
+FILE_RCSID("@(#)$File: compress.c,v 1.115 2019/02/20 02:35:27 christos Exp $")
#endif
#include "magic.h"
@@ -47,12 +47,10 @@ FILE_RCSID("@(#)$File: compress.c,v 1.107 2018/04/28 18:48:22 christos Exp $")
#include
#include
#include
-#ifdef HAVE_SIGNAL_H
#include
-# ifndef HAVE_SIG_T
+#ifndef HAVE_SIG_T
typedef void (*sig_t)(int);
-# endif /* HAVE_SIG_T */
-#endif
+#endif /* HAVE_SIG_T */
#if !defined(__MINGW32__) && !defined(WIN32)
#include
#endif
@@ -62,10 +60,17 @@ typedef void (*sig_t)(int);
#if defined(HAVE_SYS_TIME_H)
#include
#endif
+
#if defined(HAVE_ZLIB_H) && defined(ZLIBSUPPORT)
#define BUILTIN_DECOMPRESS
#include
#endif
+
+#if defined(HAVE_BZLIB_H)
+#define BUILTIN_BZLIB
+#include
+#endif
+
#ifdef DEBUG
int tty = -1;
#define DPRINTF(...) do { \
@@ -137,30 +142,34 @@ static const char *zstd_args[] = {
"zstd", "-cd", NULL
};
+#define do_zlib NULL
+#define do_bzlib NULL
+
private const struct {
const void *magic;
size_t maglen;
const char **argv;
+ void *unused;
} compr[] = {
- { "\037\235", 2, gzip_args }, /* compressed */
+ { "\037\235", 2, gzip_args, NULL }, /* compressed */
/* Uncompress can get stuck; so use gzip first if we have it
* Idea from Damien Clark, thanks! */
- { "\037\235", 2, uncompress_args }, /* compressed */
- { "\037\213", 2, gzip_args }, /* gzipped */
- { "\037\236", 2, gzip_args }, /* frozen */
- { "\037\240", 2, gzip_args }, /* SCO LZH */
+ { "\037\235", 2, uncompress_args, NULL }, /* compressed */
+ { "\037\213", 2, gzip_args, do_zlib }, /* gzipped */
+ { "\037\236", 2, gzip_args, NULL }, /* frozen */
+ { "\037\240", 2, gzip_args, NULL }, /* SCO LZH */
/* the standard pack utilities do not accept standard input */
- { "\037\036", 2, gzip_args }, /* packed */
- { "PK\3\4", 4, gzip_args }, /* pkzipped, */
+ { "\037\036", 2, gzip_args, NULL }, /* packed */
+ { "PK\3\4", 4, gzip_args, NULL }, /* pkzipped, */
/* ...only first file examined */
- { "BZh", 3, bzip2_args }, /* bzip2-ed */
- { "LZIP", 4, lzip_args }, /* lzip-ed */
- { "\3757zXZ\0", 6, xz_args }, /* XZ Utils */
- { "LRZI", 4, lrzip_args }, /* LRZIP */
- { "\004\"M\030",4, lz4_args }, /* LZ4 */
- { "\x28\xB5\x2F\xFD", 4, zstd_args }, /* zstd */
+ { "BZh", 3, bzip2_args, do_bzlib }, /* bzip2-ed */
+ { "LZIP", 4, lzip_args, NULL }, /* lzip-ed */
+ { "\3757zXZ\0", 6, xz_args, NULL }, /* XZ Utils */
+ { "LRZI", 4, lrzip_args, NULL }, /* LRZIP */
+ { "\004\"M\030",4, lz4_args, NULL }, /* LZ4 */
+ { "\x28\xB5\x2F\xFD", 4, zstd_args, NULL }, /* zstd */
#ifdef ZLIBSUPPORT
- { RCAST(const void *, zlibcmp), 0, zlib_args }, /* zlib */
+ { RCAST(const void *, zlibcmp), 0, zlib_args, NULL }, /* zlib */
#endif
};
@@ -179,6 +188,11 @@ private int uncompresszlib(const unsigned char *, unsigned char **, size_t,
private int uncompressgzipped(const unsigned char *, unsigned char **, size_t,
size_t *);
#endif
+#ifdef BUILTIN_BZLIB
+private int uncompressbzlib(const unsigned char *, unsigned char **, size_t,
+ size_t *, int);
+#endif
+
static int makeerror(unsigned char **, size_t *, const char *, ...)
__attribute__((__format__(__printf__, 3, 4)));
private const char *methodname(size_t);
@@ -210,18 +224,14 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
int urv, prv, rv = 0;
int mime = ms->flags & MAGIC_MIME;
int fd = b->fd;
- const unsigned char *buf = b->fbuf;
+ const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
-#ifdef HAVE_SIGNAL_H
sig_t osigpipe;
-#endif
if ((ms->flags & MAGIC_COMPRESS) == 0)
return 0;
-#ifdef HAVE_SIGNAL_H
osigpipe = signal(SIGPIPE, SIG_IGN);
-#endif
for (i = 0; i < ncompr; i++) {
int zm;
if (nbytes < compr[i].maglen)
@@ -238,8 +248,8 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
continue;
nsz = nbytes;
urv = uncompressbuf(fd, ms->bytes_max, i, buf, &newbuf, &nsz);
- DPRINTF("uncompressbuf = %d, %s, %zu\n", urv, (char *)newbuf,
- nsz);
+ DPRINTF("uncompressbuf = %d, %s, %" SIZE_T_FORMAT "u\n", urv,
+ (char *)newbuf, nsz);
switch (urv) {
case OKDATA:
case ERRDATA:
@@ -264,8 +274,11 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
* XXX: If file_buffer fails here, we overwrite
* the compressed text. FIXME.
*/
- if (file_buffer(ms, -1, NULL, buf, nbytes) == -1)
+ if (file_buffer(ms, -1, NULL, buf, nbytes) == -1) {
+ if (file_pop_buffer(ms, pb) != NULL)
+ abort();
goto error;
+ }
if ((rbuf = file_pop_buffer(ms, pb)) != NULL) {
if (file_printf(ms, "%s", rbuf) == -1) {
free(rbuf);
@@ -289,9 +302,7 @@ file_zmagic(struct magic_set *ms, const struct buffer *b, const char *name)
out:
DPRINTF("rv = %d\n", rv);
-#ifdef HAVE_SIGNAL_H
(void)signal(SIGPIPE, osigpipe);
-#endif
free(newbuf);
ms->flags |= MAGIC_COMPRESS;
DPRINTF("Zmagic returns %d\n", rv);
@@ -367,7 +378,7 @@ sread(int fd, void *buf, size_t n, int canbepipe __attribute__((__unused__)))
(void)ioctl(fd, FIONREAD, &t);
}
- if (t > 0 && (size_t)t < n) {
+ if (t > 0 && CAST(size_t, t) < n) {
n = t;
rn = n;
}
@@ -411,7 +422,9 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
#else
{
int te;
+ mode_t ou = umask(0);
tfd = mkstemp(buf);
+ (void)umask(ou);
te = errno;
(void)unlink(buf);
errno = te;
@@ -423,11 +436,11 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
return -1;
}
- if (swrite(tfd, startbuf, nbytes) != (ssize_t)nbytes)
+ if (swrite(tfd, startbuf, nbytes) != CAST(ssize_t, nbytes))
r = 1;
else {
while ((r = sread(fd, buf, sizeof(buf), 1)) > 0)
- if (swrite(tfd, buf, (size_t)r) != r)
+ if (swrite(tfd, buf, CAST(size_t, r)) != r)
break;
}
@@ -452,7 +465,7 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
return -1;
}
(void)close(tfd);
- if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) {
+ if (lseek(fd, CAST(off_t, 0), SEEK_SET) == CAST(off_t, -1)) {
file_badseek(ms);
return -1;
}
@@ -509,7 +522,7 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
int rc;
z_stream z;
- if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
+ if ((*newch = CAST(unsigned char *, malloc(bytes_max + 1))) == NULL)
return makeerror(newch, n, "No buffer, %s", strerror(errno));
z.next_in = CCAST(Bytef *, old);
@@ -529,18 +542,18 @@ uncompresszlib(const unsigned char *old, unsigned char **newch,
if (rc != Z_OK && rc != Z_STREAM_END)
goto err;
- *n = (size_t)z.total_out;
+ *n = CAST(size_t, z.total_out);
rc = inflateEnd(&z);
if (rc != Z_OK)
goto err;
-
+
/* let's keep the nul-terminate tradition */
(*newch)[*n] = '\0';
return OKDATA;
err:
- strlcpy((char *)*newch, z.msg ? z.msg : zError(rc), bytes_max);
- *n = strlen((char *)*newch);
+ strlcpy(RCAST(char *, *newch), z.msg ? z.msg : zError(rc), bytes_max);
+ *n = strlen(RCAST(char *, *newch));
return ERRDATA;
}
#endif
@@ -560,7 +573,7 @@ makeerror(unsigned char **buf, size_t *len, const char *fmt, ...)
*len = 0;
return NODATA;
}
- *buf = (unsigned char *)msg;
+ *buf = RCAST(unsigned char *, msg);
*len = strlen(msg);
return ERRDATA;
}
@@ -601,14 +614,14 @@ writechild(int fdp[3][2], const void *old, size_t n)
int status;
closefd(fdp[STDIN_FILENO], 0);
- /*
+ /*
* fork again, to avoid blocking because both
* pipes filled
*/
switch (fork()) {
case 0: /* child */
closefd(fdp[STDOUT_FILENO], 0);
- if (swrite(fdp[STDIN_FILENO][1], old, n) != (ssize_t)n) {
+ if (swrite(fdp[STDIN_FILENO][1], old, n) != CAST(ssize_t, n)) {
DPRINTF("Write failed (%s)\n", strerror(errno));
exit(1);
}
@@ -637,17 +650,17 @@ filter_error(unsigned char *ubuf, ssize_t n)
char *buf;
ubuf[n] = '\0';
- buf = (char *)ubuf;
- while (isspace((unsigned char)*buf))
+ buf = RCAST(char *, ubuf);
+ while (isspace(CAST(unsigned char, *buf)))
buf++;
DPRINTF("Filter error[[[%s]]]\n", buf);
- if ((p = strchr((char *)buf, '\n')) != NULL)
+ if ((p = strchr(CAST(char *, buf), '\n')) != NULL)
*p = '\0';
- if ((p = strchr((char *)buf, ';')) != NULL)
+ if ((p = strchr(CAST(char *, buf), ';')) != NULL)
*p = '\0';
- if ((p = strrchr((char *)buf, ':')) != NULL) {
+ if ((p = strrchr(CAST(char *, buf), ':')) != NULL) {
++p;
- while (isspace((unsigned char)*p))
+ while (isspace(CAST(unsigned char, *p)))
p++;
n = strlen(p);
memmove(ubuf, p, CAST(size_t, n + 1));
@@ -702,15 +715,15 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
case 0: /* child */
if (fd != -1) {
fdp[STDIN_FILENO][0] = fd;
- (void) lseek(fd, (off_t)0, SEEK_SET);
+ (void) lseek(fd, CAST(off_t, 0), SEEK_SET);
}
-
+
for (i = 0; i < __arraycount(fdp); i++)
copydesc(CAST(int, i), fdp[i]);
(void)execvp(compr[method].argv[0],
- (char *const *)(intptr_t)compr[method].argv);
- dprintf(STDERR_FILENO, "exec `%s' failed, %s",
+ RCAST(char *const *, RCAST(intptr_t, compr[method].argv)));
+ dprintf(STDERR_FILENO, "exec `%s' failed, %s",
compr[method].argv[0], strerror(errno));
exit(1);
/*NOTREACHED*/
@@ -772,8 +785,8 @@ uncompressbuf(int fd, size_t bytes_max, size_t method, const unsigned char *old,
}
closefd(fdp[STDIN_FILENO], 0);
- DPRINTF("Returning %p n=%zu rv=%d\n", *newch, *n, rv);
-
+ DPRINTF("Returning %p n=%" SIZE_T_FORMAT "u rv=%d\n", *newch, *n, rv);
+
return rv;
}
#endif
diff --git a/libmagic/src/main/cpp/file/config.h b/libmagic/src/main/cpp/file/config.h
index d7041f6..6431d3a 100644
--- a/libmagic/src/main/cpp/file/config.h
+++ b/libmagic/src/main/cpp/file/config.h
@@ -87,9 +87,6 @@
/* Define to 1 if you have the header file. */
#define HAVE_LIMITS_H 1
-/* Define to 1 if you have the header file. */
-#define HAVE_LOCALE_H 1
-
/* Define to 1 if you have the `localtime_r' function. */
#define HAVE_LOCALTIME_R 1
@@ -112,7 +109,7 @@
#define HAVE_MMAP 1
/* Define to 1 if you have the `newlocale' function. */
-//#define HAVE_NEWLOCALE 1
+#define HAVE_NEWLOCALE 1
/* Define to 1 if you have the `pread' function. */
#define HAVE_PREAD 1
@@ -120,9 +117,6 @@
/* Define to 1 if you have the `setlocale' function. */
#define HAVE_SETLOCALE 1
-/* Define to 1 if you have the header file. */
-#define HAVE_SIGNAL_H 1
-
/* Have sig_t type */
#define HAVE_SIG_T 1
@@ -277,7 +271,7 @@
#define PACKAGE_NAME "file"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "file 5.34"
+#define PACKAGE_STRING "file 5.36"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "file"
@@ -286,7 +280,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "5.34"
+#define PACKAGE_VERSION "5.36"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -317,7 +311,7 @@
/* Version number of package */
-#define VERSION "5.34"
+#define VERSION "5.36"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
diff --git a/libmagic/src/main/cpp/file/der.c b/libmagic/src/main/cpp/file/der.c
index d017b63..8867c56 100644
--- a/libmagic/src/main/cpp/file/der.c
+++ b/libmagic/src/main/cpp/file/der.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: der.c,v 1.13 2018/06/23 15:15:26 christos Exp $")
+FILE_RCSID("@(#)$File: der.c,v 1.16 2019/02/20 02:35:27 christos Exp $")
#endif
#endif
@@ -56,7 +56,7 @@ FILE_RCSID("@(#)$File: der.c,v 1.13 2018/06/23 15:15:26 christos Exp $")
#include
#endif
-#define DER_BAD ((uint32_t)-1)
+#define DER_BAD CAST(uint32_t, -1)
#define DER_CLASS_UNIVERSAL 0
#define DER_CLASS_APPLICATION 1
@@ -207,7 +207,7 @@ getlength(const uint8_t *c, size_t *p, size_t l)
static const char *
der_tag(char *buf, size_t len, uint32_t tag)
{
- if (tag < DER_TAG_LONG)
+ if (tag < DER_TAG_LONG)
strlcpy(buf, der__tag[tag], len);
else
snprintf(buf, len, "%#x", tag);
@@ -224,11 +224,11 @@ der_data(char *buf, size_t blen, uint32_t tag, const void *q, uint32_t len)
case DER_TAG_UTF8_STRING:
case DER_TAG_IA5_STRING:
case DER_TAG_UTCTIME:
- return snprintf(buf, blen, "%.*s", len, (const char *)q);
+ return snprintf(buf, blen, "%.*s", len, RCAST(const char *, q));
default:
break;
}
-
+
for (uint32_t i = 0; i < len; i++) {
uint32_t z = i << 1;
if (z < blen - 2)
@@ -245,18 +245,21 @@ der_offs(struct magic_set *ms, struct magic *m, size_t nbytes)
if (gettag(b, &offs, len) == DER_BAD)
return -1;
- DPRINTF(("%s1: %d %zu %u\n", __func__, ms->offset, offs, m->offset));
+ DPRINTF(("%s1: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
+ offs, m->offset));
uint32_t tlen = getlength(b, &offs, len);
if (tlen == DER_BAD)
return -1;
- DPRINTF(("%s2: %d %zu %u\n", __func__, ms->offset, offs, tlen));
+ DPRINTF(("%s2: %d %" SIZE_T_FORMAT "u %u\n", __func__, ms->offset,
+ offs, tlen));
offs += ms->offset + m->offset;
DPRINTF(("cont_level = %d\n", m->cont_level));
#ifdef DEBUG_DER
for (size_t i = 0; i < m->cont_level; i++)
- printf("cont_level[%zu] = %u\n", i, ms->c.li[i].off);
+ printf("cont_level[%" SIZE_T_FORMAT "u] = %u\n", i,
+ ms->c.li[i].off);
#endif
if (m->cont_level != 0) {
if (offs + tlen > nbytes)
@@ -304,22 +307,23 @@ der_cmp(struct magic_set *ms, struct magic *m)
s++;
goto val;
default:
- if (!isdigit((unsigned char)*s))
+ if (!isdigit(CAST(unsigned char, *s)))
return 0;
slen = 0;
do
slen = slen * 10 + *s - '0';
- while (isdigit((unsigned char)*++s));
+ while (isdigit(CAST(unsigned char, *++s)));
if ((ms->flags & MAGIC_DEBUG) != 0)
- fprintf(stderr, "%s: len %zu %u\n", __func__,
- slen, tlen);
+ fprintf(stderr, "%s: len %" SIZE_T_FORMAT "u %u\n",
+ __func__, slen, tlen);
if (tlen != slen)
return 0;
goto again;
}
val:
- DPRINTF(("%s: before data %zu %u\n", __func__, offs, tlen));
+ DPRINTF(("%s: before data %" SIZE_T_FORMAT "u %u\n", __func__, offs,
+ tlen));
der_data(buf, sizeof(buf), tag, b + offs, tlen);
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "%s: data %s %s\n", __func__, buf, s);
@@ -343,7 +347,7 @@ printtag(uint32_t tag, const void *q, uint32_t len)
default:
break;
}
-
+
for (uint32_t i = 0; i < len; i++)
printf("%.2x", d[i]);
printf("\n");
@@ -367,8 +371,9 @@ printdata(size_t level, const void *v, size_t x, size_t l)
if (p + x >= ep)
break;
uint32_t len = getlength(p, &x, ep - p + x);
-
- printf("%zu %zu-%zu %c,%c,%s,%u:", level, ox, x,
+
+ printf("%" SIZE_T_FORMAT "u %" SIZE_T_FORMAT "u-%"
+ SIZE_T_FORMAT "u %c,%c,%s,%u:", level, ox, x,
der_class[c], der_type[t],
der_tag(buf, sizeof(buf), tag), len);
q = p + x;
diff --git a/libmagic/src/main/cpp/file/dprintf.c b/libmagic/src/main/cpp/file/dprintf.c
index 5d9c58b..027a64f 100644
--- a/libmagic/src/main/cpp/file/dprintf.c
+++ b/libmagic/src/main/cpp/file/dprintf.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 THE AUTHOR AND 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
@@ -28,7 +28,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: dprintf.c,v 1.13 2014/12/04 15:56:46 christos Exp $")
+FILE_RCSID("@(#)$File: dprintf.c,v 1.2 2018/09/09 20:33:28 christos Exp $")
#endif /* lint */
#include
diff --git a/libmagic/src/main/cpp/file/elfclass.h b/libmagic/src/main/cpp/file/elfclass.h
index 5360b0b..936d8dc 100644
--- a/libmagic/src/main/cpp/file/elfclass.h
+++ b/libmagic/src/main/cpp/file/elfclass.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) Christos Zoulas 2008.
* All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -11,7 +11,7 @@
* 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 THE AUTHOR AND 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
@@ -41,8 +41,8 @@
return toomany(ms, "program headers", phnum);
flags |= FLAGS_IS_CORE;
if (dophn_core(ms, clazz, swap, fd,
- (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
+ CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
fsize, &flags, ¬ecount) == -1)
return -1;
break;
@@ -56,8 +56,8 @@
if (shnum > ms->elf_shnum_max)
return toomany(ms, "section", shnum);
if (dophn_exec(ms, clazz, swap, fd,
- (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
- (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ CAST(off_t, elf_getu(swap, elfhdr.e_phoff)), phnum,
+ CAST(size_t, elf_getu16(swap, elfhdr.e_phentsize)),
fsize, shnum, &flags, ¬ecount) == -1)
return -1;
/*FALLTHROUGH*/
@@ -66,10 +66,10 @@
if (shnum > ms->elf_shnum_max)
return toomany(ms, "section headers", shnum);
if (doshn(ms, clazz, swap, fd,
- (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
- (size_t)elf_getu16(swap, elfhdr.e_shentsize),
+ CAST(off_t, elf_getu(swap, elfhdr.e_shoff)), shnum,
+ CAST(size_t, elf_getu16(swap, elfhdr.e_shentsize)),
fsize, elf_getu16(swap, elfhdr.e_machine),
- (int)elf_getu16(swap, elfhdr.e_shstrndx),
+ CAST(int, elf_getu16(swap, elfhdr.e_shstrndx)),
&flags, ¬ecount) == -1)
return -1;
break;
diff --git a/libmagic/src/main/cpp/file/encoding.c b/libmagic/src/main/cpp/file/encoding.c
index 3e7b9e5..81cd925 100644
--- a/libmagic/src/main/cpp/file/encoding.c
+++ b/libmagic/src/main/cpp/file/encoding.c
@@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: encoding.c,v 1.14 2017/11/02 20:25:39 christos Exp $")
+FILE_RCSID("@(#)$File: encoding.c,v 1.17 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -49,6 +49,7 @@ private int looks_utf8_with_BOM(const unsigned char *, size_t, unichar *,
size_t *);
private int looks_utf7(const unsigned char *, size_t, unichar *, size_t *);
private int looks_ucs16(const unsigned char *, size_t, unichar *, size_t *);
+private int looks_ucs32(const unsigned char *, size_t, unichar *, size_t *);
private int looks_latin1(const unsigned char *, size_t, unichar *, size_t *);
private int looks_extended(const unsigned char *, size_t, unichar *, size_t *);
private void from_ebcdic(const unsigned char *, size_t, unsigned char *);
@@ -69,7 +70,7 @@ protected int
file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
size_t *ulen, const char **code, const char **code_mime, const char **type)
{
- const unsigned char *buf = b->fbuf;
+ const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
size_t mlen;
int rv = 1, ucs_type;
@@ -88,12 +89,12 @@ file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
*code_mime = "binary";
mlen = (nbytes + 1) * sizeof((*ubuf)[0]);
- if ((*ubuf = CAST(unichar *, calloc((size_t)1, mlen))) == NULL) {
+ if ((*ubuf = CAST(unichar *, calloc(CAST(size_t, 1), mlen))) == NULL) {
file_oomem(ms, mlen);
goto done;
}
mlen = (nbytes + 1) * sizeof(nbuf[0]);
- if ((nbuf = CAST(unsigned char *, calloc((size_t)1, mlen))) == NULL) {
+ if ((nbuf = CAST(unsigned char *, calloc(CAST(size_t, 1), mlen))) == NULL) {
file_oomem(ms, mlen);
goto done;
}
@@ -116,6 +117,15 @@ file_encoding(struct magic_set *ms, const struct buffer *b, unichar **ubuf,
DPRINTF(("utf8 %" SIZE_T_FORMAT "u\n", *ulen));
*code = "UTF-8 Unicode";
*code_mime = "utf-8";
+ } else if ((ucs_type = looks_ucs32(buf, nbytes, *ubuf, ulen)) != 0) {
+ if (ucs_type == 1) {
+ *code = "Little-endian UTF-32 Unicode";
+ *code_mime = "utf-32le";
+ } else {
+ *code = "Big-endian UTF-32 Unicode";
+ *code_mime = "utf-32be";
+ }
+ DPRINTF(("ucs32 %" SIZE_T_FORMAT "u\n", *ulen));
} else if ((ucs_type = looks_ucs16(buf, nbytes, *ubuf, ulen)) != 0) {
if (ucs_type == 1) {
*code = "Little-endian UTF-16 Unicode";
@@ -410,7 +420,7 @@ looks_utf7(const unsigned char *buf, size_t nbytes, unichar *ubuf, size_t *ulen)
}
private int
-looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
+looks_ucs16(const unsigned char *bf, size_t nbytes, unichar *ubf,
size_t *ulen)
{
int bigend;
@@ -419,9 +429,9 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
if (nbytes < 2)
return 0;
- if (buf[0] == 0xff && buf[1] == 0xfe)
+ if (bf[0] == 0xff && bf[1] == 0xfe)
bigend = 0;
- else if (buf[0] == 0xfe && buf[1] == 0xff)
+ else if (bf[0] == 0xfe && bf[1] == 0xff)
bigend = 1;
else
return 0;
@@ -432,20 +442,58 @@ looks_ucs16(const unsigned char *buf, size_t nbytes, unichar *ubuf,
/* XXX fix to properly handle chars > 65536 */
if (bigend)
- ubuf[(*ulen)++] = buf[i + 1] + 256 * buf[i];
+ ubf[(*ulen)++] = bf[i + 1] + 256 * bf[i];
else
- ubuf[(*ulen)++] = buf[i] + 256 * buf[i + 1];
+ ubf[(*ulen)++] = bf[i] + 256 * bf[i + 1];
- if (ubuf[*ulen - 1] == 0xfffe)
+ if (ubf[*ulen - 1] == 0xfffe)
return 0;
- if (ubuf[*ulen - 1] < 128 &&
- text_chars[(size_t)ubuf[*ulen - 1]] != T)
+ if (ubf[*ulen - 1] < 128 &&
+ text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
return 0;
}
return 1 + bigend;
}
+private int
+looks_ucs32(const unsigned char *bf, size_t nbytes, unichar *ubf,
+ size_t *ulen)
+{
+ int bigend;
+ size_t i;
+
+ if (nbytes < 4)
+ return 0;
+
+ if (bf[0] == 0xff && bf[1] == 0xfe && bf[2] == 0 && bf[3] == 0)
+ bigend = 0;
+ else if (bf[0] == 0 && bf[1] == 0 && bf[2] == 0xfe && bf[3] == 0xff)
+ bigend = 1;
+ else
+ return 0;
+
+ *ulen = 0;
+
+ for (i = 4; i + 1 < nbytes; i += 4) {
+ /* XXX fix to properly handle chars > 65536 */
+
+ if (bigend)
+ ubf[(*ulen)++] = bf[i + 3] | (bf[i + 2] << 8)
+ | (bf[i + 1] << 16) | bf[i] << 24;
+ else
+ ubf[(*ulen)++] = bf[i] | (bf[i + 1] << 8)
+ | (bf[i + 2] << 16) | (bf[i + 3] << 24);
+
+ if (ubf[*ulen - 1] == 0xfffe)
+ return 0;
+ if (ubf[*ulen - 1] < 128 &&
+ text_chars[CAST(size_t, ubf[*ulen - 1])] != T)
+ return 0;
+ }
+
+ return 1 + bigend;
+}
#undef F
#undef T
#undef I
diff --git a/libmagic/src/main/cpp/file/file.c b/libmagic/src/main/cpp/file/file.c
index 87dd1bb..5f0303e 100644
--- a/libmagic/src/main/cpp/file/file.c
+++ b/libmagic/src/main/cpp/file/file.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: file.c,v 1.175 2018/03/02 16:11:37 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.179 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -128,6 +128,7 @@ private const struct {
{ "encoding", MAGIC_NO_CHECK_ENCODING },
{ "soft", MAGIC_NO_CHECK_SOFT },
{ "tar", MAGIC_NO_CHECK_TAR },
+ { "json", MAGIC_NO_CHECK_JSON },
{ "text", MAGIC_NO_CHECK_TEXT }, /* synonym for ascii */
{ "tokens", MAGIC_NO_CHECK_TOKENS }, /* OBSOLETE: ignored for backwards compatibility */
};
@@ -136,14 +137,15 @@ private struct {
const char *name;
int tag;
size_t value;
+ int set;
} pm[] = {
- { "indir", MAGIC_PARAM_INDIR_MAX, 0 },
- { "name", MAGIC_PARAM_NAME_MAX, 0 },
- { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0 },
- { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0 },
- { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0 },
- { "regex", MAGIC_PARAM_REGEX_MAX, 0 },
- { "bytes", MAGIC_PARAM_BYTES_MAX, 0 },
+ { "indir", MAGIC_PARAM_INDIR_MAX, 0, 0 },
+ { "name", MAGIC_PARAM_NAME_MAX, 0, 0 },
+ { "elf_phnum", MAGIC_PARAM_ELF_PHNUM_MAX, 0, 0 },
+ { "elf_shnum", MAGIC_PARAM_ELF_SHNUM_MAX, 0, 0 },
+ { "elf_notes", MAGIC_PARAM_ELF_NOTES_MAX, 0, 0 },
+ { "regex", MAGIC_PARAM_REGEX_MAX, 0, 0 },
+ { "bytes", MAGIC_PARAM_BYTES_MAX, 0, 0 },
};
private int posixly;
@@ -398,7 +400,8 @@ main(int argc, char *argv[])
}
else {
size_t j, wid, nw;
- for (wid = 0, j = (size_t)optind; j < (size_t)argc; j++) {
+ for (wid = 0, j = CAST(size_t, optind); j < CAST(size_t, argc);
+ j++) {
nw = file_mbswidth(argv[j]);
if (nw > wid)
wid = nw;
@@ -426,7 +429,7 @@ applyparam(magic_t magic)
size_t i;
for (i = 0; i < __arraycount(pm); i++) {
- if (pm[i].value == 0)
+ if (!pm[i].set)
continue;
if (magic_setparam(magic, pm[i].tag, &pm[i].value) == -1)
file_err(EXIT_FAILURE, "Can't set %s", pm[i].name);
@@ -446,6 +449,7 @@ setparam(const char *p)
if (strncmp(p, pm[i].name, s - p) != 0)
continue;
pm[i].value = atoi(s + 1);
+ pm[i].set = 1;
return;
}
badparm:
@@ -534,9 +538,8 @@ process(struct magic_set *ms, const char *inname, int wid)
(void)putc('\0', stdout);
if (nulsep < 2) {
(void)printf("%s", separator);
- (void)printf("%*s ",
- (int) (nopad ? 0 : (wid - file_mbswidth(inname))),
- "");
+ (void)printf("%*s ", CAST(int, nopad ? 0
+ : (wid - file_mbswidth(inname))), "");
}
}
@@ -563,8 +566,8 @@ file_mbswidth(const char *s)
while (n > 0) {
bytesconsumed = mbrtowc(&nextchar, s, n, &state);
- if (bytesconsumed == (size_t)(-1) ||
- bytesconsumed == (size_t)(-2)) {
+ if (bytesconsumed == CAST(size_t, -1) ||
+ bytesconsumed == CAST(size_t, -2)) {
/* Something went wrong, return something reasonable */
return old_n;
}
@@ -623,13 +626,13 @@ docprint(const char *opts, int def)
for (sp = p - 1; sp > opts && *sp == ' '; sp--)
continue;
- fprintf(stdout, "%.*s", (int)(p - opts), opts);
+ fprintf(stdout, "%.*s", CAST(int, p - opts), opts);
comma = 0;
for (i = 0; i < __arraycount(nv); i++) {
fprintf(stdout, "%s%s", comma++ ? ", " : "", nv[i].name);
- if (i && i % 5 == 0) {
- fprintf(stdout, ",\n%*s", (int)(p - sp - 1), "");
+ if (i && i % 5 == 0 && i != __arraycount(nv) - 1) {
+ fprintf(stdout, ",\n%*s", CAST(int, p - sp - 1), "");
comma = 0;
}
}
@@ -653,7 +656,7 @@ help(void)
#include "file_opts.h"
#undef OPT
#undef OPT_LONGONLY
- fprintf(stdout, "\nReport bugs to http://bugs.gw.com/\n");
+ fprintf(stdout, "\nReport bugs to https://bugs.astron.com/\n");
exit(EXIT_SUCCESS);
}
diff --git a/libmagic/src/main/cpp/file/file.h b/libmagic/src/main/cpp/file/file.h
index 57a84a8..f8e0835 100644
--- a/libmagic/src/main/cpp/file/file.h
+++ b/libmagic/src/main/cpp/file/file.h
@@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.193 2018/05/24 18:09:17 christos Exp $
+ * @(#)$File: file.h,v 1.202 2019/02/18 17:46:56 christos Exp $
*/
#ifndef __file_h__
@@ -40,6 +40,9 @@
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
#ifdef WIN32
#ifdef _WIN64
@@ -379,7 +382,7 @@ struct mlist {
#define CCAST(T, b) const_cast(b)
#else
#define CAST(T, b) ((T)(b))
-#define RCAST(T, b) ((T)(b))
+#define RCAST(T, b) ((T)(uintptr_t)(b))
#define CCAST(T, b) ((T)(uintptr_t)(b))
#endif
@@ -450,6 +453,7 @@ struct stat;
protected const char *file_fmttime(uint64_t, int, char *);
protected struct magic_set *file_ms_alloc(int);
protected void file_ms_free(struct magic_set *);
+protected int file_default(struct magic_set *, size_t);
protected int file_buffer(struct magic_set *, int, const char *, const void *,
size_t);
protected int file_fsmagic(struct magic_set *, const char *, struct stat *);
@@ -473,6 +477,7 @@ protected int file_ascmagic_with_encoding(struct magic_set *,
const struct buffer *, unichar *, size_t, const char *, const char *, int);
protected int file_encoding(struct magic_set *, const struct buffer *,
unichar **, size_t *, const char **, const char **, const char **);
+protected int file_is_json(struct magic_set *, const struct buffer *);
protected int file_is_tar(struct magic_set *, const struct buffer *);
protected int file_softmagic(struct magic_set *, const struct buffer *,
uint16_t *, uint16_t *, int, int);
@@ -501,7 +506,7 @@ protected int file_looks_utf8(const unsigned char *, size_t, unichar *,
size_t *);
protected size_t file_pstring_length_size(const struct magic *);
protected size_t file_pstring_get_length(const struct magic *, const char *);
-protected char * file_printable(char *, size_t, const char *);
+protected char * file_printable(char *, size_t, const char *, size_t);
#ifdef __EMX__
protected int file_os2_apptype(struct magic_set *, const char *, const void *,
size_t);
@@ -511,9 +516,7 @@ protected void buffer_init(struct buffer *, int, const void *, size_t);
protected void buffer_fini(struct buffer *);
protected int buffer_fill(const struct buffer *);
-#if defined(HAVE_LOCALE_H)
#include
-#endif
#if defined(HAVE_XLOCALE_H)
#include
#endif
@@ -600,17 +603,17 @@ struct tm *gmtime_r(const time_t *, struct tm *);
struct tm *localtime_r(const time_t *, struct tm *);
#endif
#ifndef HAVE_FMTCHECK
-const char *fmtcheck(const char *, const char *)
+const char *fmtcheck(const char *, const char *)
__attribute__((__format_arg__(2)));
#endif
#ifdef HAVE_LIBSECCOMP
-// basic filter
+// basic filter
// this mode should not interfere with normal operations
// only some dangerous syscalls are blacklisted
int enable_sandbox_basic(void);
-// enhanced filter
+// enhanced filter
// this mode allows only the necessary syscalls used during normal operation
// extensive testing required !!!
int enable_sandbox_full(void);
@@ -634,6 +637,9 @@ protected void file_warnx(const char *, ...)
#ifndef O_BINARY
#define O_BINARY 0
#endif
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 0
+#endif
#ifndef __cplusplus
#if defined(__GNUC__) && (__GNUC__ >= 3)
diff --git a/libmagic/src/main/cpp/file/fmtcheck.c b/libmagic/src/main/cpp/file/fmtcheck.c
index 486aa08..fcad436 100644
--- a/libmagic/src/main/cpp/file/fmtcheck.c
+++ b/libmagic/src/main/cpp/file/fmtcheck.c
@@ -235,7 +235,7 @@ fmtcheck(const char *f1, const char *f2)
EFT f1t, f2t;
if (!f1) return f2;
-
+
f1p = f1;
f1t = FMTCHECK_START;
f2p = f2;
diff --git a/libmagic/src/main/cpp/file/fsmagic.c b/libmagic/src/main/cpp/file/fsmagic.c
index c0a437a..3d74255 100644
--- a/libmagic/src/main/cpp/file/fsmagic.c
+++ b/libmagic/src/main/cpp/file/fsmagic.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 THE AUTHOR AND 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
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: fsmagic.c,v 1.77 2017/05/24 19:17:50 christos Exp $")
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.79 2018/10/02 00:38:33 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -77,7 +77,7 @@ bad_link(struct magic_set *ms, int err, char *buf)
file_error(ms, err,
"broken symbolic link to %s", buf);
return -1;
- }
+ }
if (file_printf(ms, "broken symbolic link to %s", buf) == -1)
return -1;
}
@@ -174,17 +174,17 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
return -1;
#endif
#ifdef S_ISGID
- if (sb->st_mode & S_ISGID)
+ if (sb->st_mode & S_ISGID)
if (file_printf(ms, "%ssetgid", COMMA) == -1)
return -1;
#endif
#ifdef S_ISVTX
- if (sb->st_mode & S_ISVTX)
+ if (sb->st_mode & S_ISVTX)
if (file_printf(ms, "%ssticky", COMMA) == -1)
return -1;
#endif
}
-
+
switch (sb->st_mode & S_IFMT) {
case S_IFDIR:
if (mime) {
@@ -196,7 +196,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
break;
#ifdef S_IFCHR
case S_IFCHR:
- /*
+ /*
* If -s has been specified, treat character special files
* like ordinary files. Otherwise, just report that they
* are block special files and go on to the next file.
@@ -231,7 +231,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
#endif
#ifdef S_IFBLK
case S_IFBLK:
- /*
+ /*
* If -s has been specified, treat block special files
* like ordinary files. Otherwise, just report that they
* are block special files and go on to the next file.
@@ -308,6 +308,15 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
buf[nch] = '\0'; /* readlink(2) does not do this */
/* If broken symlink, say so and quit early. */
+#ifdef __linux__
+ /*
+ * linux procfs/devfs makes symlinks like pipe:[3515864880]
+ * that we can't stat their readlink output, so stat the
+ * original filename instead.
+ */
+ if (stat(fn, &tstatbuf) < 0)
+ return bad_link(ms, errno, buf);
+#else
if (*buf == '/') {
if (stat(buf, &tstatbuf) < 0)
return bad_link(ms, errno, buf);
@@ -320,7 +329,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
} else {
if (tmp - fn + 1 > BUFSIZ) {
if (ms->flags & MAGIC_ERROR) {
- file_error(ms, 0,
+ file_error(ms, 0,
"path too long: `%s'", buf);
return -1;
}
@@ -345,6 +354,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
if (stat(tmp, &tstatbuf) < 0)
return bad_link(ms, errno, buf);
}
+#endif
/* Otherwise, handle it. */
if ((ms->flags & MAGIC_SYMLINK) != 0) {
diff --git a/libmagic/src/main/cpp/file/funcs.c b/libmagic/src/main/cpp/file/funcs.c
index 0bf92fe..eca99ad 100644
--- a/libmagic/src/main/cpp/file/funcs.c
+++ b/libmagic/src/main/cpp/file/funcs.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: funcs.c,v 1.95 2018/05/24 18:09:17 christos Exp $")
+FILE_RCSID("@(#)$File: funcs.c,v 1.102 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -42,9 +42,7 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.95 2018/05/24 18:09:17 christos Exp $")
#if defined(HAVE_WCTYPE_H)
#include
#endif
-#if defined(HAVE_LIMITS_H)
#include
-#endif
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)~0)
@@ -107,13 +105,13 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va,
if (lineno != 0) {
free(ms->o.buf);
ms->o.buf = NULL;
- file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
+ (void)file_printf(ms, "line %" SIZE_T_FORMAT "u:", lineno);
}
if (ms->o.buf && *ms->o.buf)
- file_printf(ms, " ");
- file_vprintf(ms, f, va);
+ (void)file_printf(ms, " ");
+ (void)file_vprintf(ms, f, va);
if (error > 0)
- file_printf(ms, " (%s)", strerror(error));
+ (void)file_printf(ms, " (%s)", strerror(error));
ms->event_flags |= EVENT_HAD_ERR;
ms->error = error;
}
@@ -172,6 +170,35 @@ checkdone(struct magic_set *ms, int *rv)
return 0;
}
+protected int
+file_default(struct magic_set *ms, size_t nb)
+{
+ if (ms->flags & MAGIC_MIME) {
+ if ((ms->flags & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/%s",
+ nb ? "octet-stream" : "x-empty") == -1)
+ return -1;
+ return 1;
+ }
+ if (ms->flags & MAGIC_APPLE) {
+ if (file_printf(ms, "UNKNUNKN") == -1)
+ return -1;
+ return 1;
+ }
+ if (ms->flags & MAGIC_EXTENSION) {
+ if (file_printf(ms, "???") == -1)
+ return -1;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * The magic detection functions return:
+ * 1: found
+ * 0: not found
+ * -1: error
+ */
/*ARGSUSED*/
protected int
file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__unused__)),
@@ -180,7 +207,6 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
int m = 0, rv = 0, looks_text = 0;
const char *code = NULL;
const char *code_mime = "binary";
- const char *type = "application/octet-stream";
const char *def = "data";
const char *ftype = NULL;
char *rbuf = NULL;
@@ -191,7 +217,6 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
if (nb == 0) {
def = "empty";
- type = "application/x-empty";
goto simple;
} else if (nb == 1) {
def = "very short file (no magic)";
@@ -240,6 +265,17 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
}
}
+ /* Check if we have a JSON file */
+ if ((ms->flags & MAGIC_NO_CHECK_JSON) == 0) {
+ m = file_is_json(ms, &b);
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ (void)fprintf(stderr, "[try json %d]\n", m);
+ if (m) {
+ if (checkdone(ms, &rv))
+ goto done;
+ }
+ }
+
/* Check if we have a CDF file */
if ((ms->flags & MAGIC_NO_CHECK_CDF) == 0) {
m = file_trycdf(ms, &b);
@@ -268,7 +304,7 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
rv = file_tryelf(ms, &b);
rbuf = file_pop_buffer(ms, pb);
- if (rv != 1) {
+ if (rv == -1) {
free(rbuf);
rbuf = NULL;
}
@@ -306,20 +342,12 @@ file_buffer(struct magic_set *ms, int fd, const char *inname __attribute__ ((__u
simple:
/* give up */
- m = 1;
- if (ms->flags & MAGIC_MIME) {
- if ((ms->flags & MAGIC_MIME_TYPE) &&
- file_printf(ms, "%s", type) == -1)
- rv = -1;
- } else if (ms->flags & MAGIC_APPLE) {
- if (file_printf(ms, "UNKNUNKN") == -1)
- rv = -1;
- } else if (ms->flags & MAGIC_EXTENSION) {
- if (file_printf(ms, "???") == -1)
- rv = -1;
- } else {
- if (file_printf(ms, "%s", def) == -1)
- rv = -1;
+ if (m == 0) {
+ m = 1;
+ rv = file_default(ms, nb);
+ if (rv == 0)
+ if (file_printf(ms, "%s", def) == -1)
+ rv = -1;
}
done:
if ((ms->flags & MAGIC_MIME_ENCODING) != 0) {
@@ -364,9 +392,9 @@ file_reset(struct magic_set *ms, int checkloaded)
#define OCTALIFY(n, o) \
/*LINTED*/ \
(void)(*(n)++ = '\\', \
- *(n)++ = (((uint32_t)*(o) >> 6) & 3) + '0', \
- *(n)++ = (((uint32_t)*(o) >> 3) & 7) + '0', \
- *(n)++ = (((uint32_t)*(o) >> 0) & 7) + '0', \
+ *(n)++ = ((CAST(uint32_t, *(o)) >> 6) & 3) + '0', \
+ *(n)++ = ((CAST(uint32_t, *(o)) >> 3) & 7) + '0', \
+ *(n)++ = ((CAST(uint32_t, *(o)) >> 0) & 7) + '0', \
(o)++)
protected const char *
@@ -412,9 +440,9 @@ file_getbuffer(struct magic_set *ms)
while (op < eop) {
bytesconsumed = mbrtowc(&nextchar, op,
- (size_t)(eop - op), &state);
- if (bytesconsumed == (size_t)(-1) ||
- bytesconsumed == (size_t)(-2)) {
+ CAST(size_t, eop - op), &state);
+ if (bytesconsumed == CAST(size_t, -1) ||
+ bytesconsumed == CAST(size_t, -2)) {
mb_conv = 0;
break;
}
@@ -437,7 +465,7 @@ file_getbuffer(struct magic_set *ms)
#endif
for (np = ms->o.pbuf, op = ms->o.buf; *op;) {
- if (isprint((unsigned char)*op)) {
+ if (isprint(CAST(unsigned char, *op))) {
*np++ = *op++;
} else {
OCTALIFY(np, op);
@@ -595,12 +623,13 @@ file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
* convert string to ascii printable format.
*/
protected char *
-file_printable(char *buf, size_t bufsiz, const char *str)
+file_printable(char *buf, size_t bufsiz, const char *str, size_t slen)
{
- char *ptr, *eptr;
- const unsigned char *s = (const unsigned char *)str;
+ char *ptr, *eptr = buf + bufsiz - 1;
+ const unsigned char *s = RCAST(const unsigned char *, str);
+ const unsigned char *es = s + slen;
- for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) {
+ for (ptr = buf; ptr < eptr && s < es && *s; s++) {
if (isprint(*s)) {
*ptr++ = *s;
continue;
diff --git a/libmagic/src/main/cpp/file/getopt_long.c b/libmagic/src/main/cpp/file/getopt_long.c
deleted file mode 100644
index f0fb1b0..0000000
--- a/libmagic/src/main/cpp/file/getopt_long.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/* $NetBSD: getopt_long.c,v 1.21.4.1 2008/01/09 01:34:14 matt Exp $ */
-
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Dieter Baron and Thomas Klausner.
- *
- * 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 THE NETBSD FOUNDATION, INC. AND 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 THE FOUNDATION OR 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 "file.h"
-
-#ifndef lint
-FILE_RCSID("@(#)$File: getopt_long.c,v 1.5 2009/02/03 20:27:51 christos Exp $")
-#endif /* lint */
-
-#include
-#ifdef HAVE_ERR_H
-#include
-#else
-#define warnx printf
-#endif
-#include
-#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION)
-#include
-#else
-#include "mygetopt.h"
-#endif
-#include
-#include
-
-#define REPLACE_GETOPT
-
-#ifndef _DIAGASSERT
-#define _DIAGASSERT assert
-#endif
-
-#ifdef REPLACE_GETOPT
-#ifdef __weak_alias
-__weak_alias(getopt,_getopt)
-#endif
-int opterr = 1; /* if error message should be printed */
-int optind = 1; /* index into parent argv vector */
-int optopt = '?'; /* character checked for validity */
-int optreset; /* reset getopt */
-char *optarg; /* argument associated with option */
-#elif HAVE_NBTOOL_CONFIG_H && !HAVE_DECL_OPTRESET
-static int optreset;
-#endif
-
-#ifdef __weak_alias
-__weak_alias(getopt_long,_getopt_long)
-#endif
-
-#define IGNORE_FIRST (*options == '-' || *options == '+')
-#define PRINT_ERROR ((opterr) && ((*options != ':') \
- || (IGNORE_FIRST && options[1] != ':')))
-#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL)
-#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST)
-/* XXX: GNU ignores PC if *options == '-' */
-#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-')
-
-/* return values */
-#define BADCH (int)'?'
-#define BADARG ((IGNORE_FIRST && options[1] == ':') \
- || (*options == ':') ? (int)':' : (int)'?')
-#define INORDER (int)1
-
-#define EMSG ""
-
-static int getopt_internal(int, char **, const char *);
-static int gcd(int, int);
-static void permute_args(int, int, int, char **);
-
-static const char *place = EMSG; /* option letter processing */
-
-/* XXX: set optreset to 1 rather than these two */
-static int nonopt_start = -1; /* first non option argument (for permute) */
-static int nonopt_end = -1; /* first option after non options (for permute) */
-
-/* Error messages */
-static const char recargchar[] = "option requires an argument -- %c";
-static const char recargstring[] = "option requires an argument -- %s";
-static const char ambig[] = "ambiguous option -- %.*s";
-static const char noarg[] = "option doesn't take an argument -- %.*s";
-static const char illoptchar[] = "unknown option -- %c";
-static const char illoptstring[] = "unknown option -- %s";
-
-
-/*
- * Compute the greatest common divisor of a and b.
- */
-static int
-gcd(a, b)
- int a;
- int b;
-{
- int c;
-
- c = a % b;
- while (c != 0) {
- a = b;
- b = c;
- c = a % b;
- }
-
- return b;
-}
-
-/*
- * Exchange the block from nonopt_start to nonopt_end with the block
- * from nonopt_end to opt_end (keeping the same order of arguments
- * in each block).
- */
-static void
-permute_args(panonopt_start, panonopt_end, opt_end, nargv)
- int panonopt_start;
- int panonopt_end;
- int opt_end;
- char **nargv;
-{
- int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
- char *swap;
-
- _DIAGASSERT(nargv != NULL);
-
- /*
- * compute lengths of blocks and number and size of cycles
- */
- nnonopts = panonopt_end - panonopt_start;
- nopts = opt_end - panonopt_end;
- ncycle = gcd(nnonopts, nopts);
- cyclelen = (opt_end - panonopt_start) / ncycle;
-
- for (i = 0; i < ncycle; i++) {
- cstart = panonopt_end+i;
- pos = cstart;
- for (j = 0; j < cyclelen; j++) {
- if (pos >= panonopt_end)
- pos -= nnonopts;
- else
- pos += nopts;
- swap = nargv[pos];
- nargv[pos] = nargv[cstart];
- nargv[cstart] = swap;
- }
- }
-}
-
-/*
- * getopt_internal --
- * Parse argc/argv argument vector. Called by user level routines.
- * Returns -2 if -- is found (can be long option or end of options marker).
- */
-static int
-getopt_internal(nargc, nargv, options)
- int nargc;
- char **nargv;
- const char *options;
-{
- char *oli; /* option letter list index */
- int optchar;
-
- _DIAGASSERT(nargv != NULL);
- _DIAGASSERT(options != NULL);
-
- optarg = NULL;
-
- /*
- * XXX Some programs (like rsyncd) expect to be able to
- * XXX re-initialize optind to 0 and have getopt_long(3)
- * XXX properly function again. Work around this braindamage.
- */
- if (optind == 0)
- optind = 1;
-
- if (optreset)
- nonopt_start = nonopt_end = -1;
-start:
- if (optreset || !*place) { /* update scanning pointer */
- optreset = 0;
- if (optind >= nargc) { /* end of argument vector */
- place = EMSG;
- if (nonopt_end != -1) {
- /* do permutation, if we have to */
- permute_args(nonopt_start, nonopt_end,
- optind, nargv);
- optind -= nonopt_end - nonopt_start;
- }
- else if (nonopt_start != -1) {
- /*
- * If we skipped non-options, set optind
- * to the first of them.
- */
- optind = nonopt_start;
- }
- nonopt_start = nonopt_end = -1;
- return -1;
- }
- if ((*(place = nargv[optind]) != '-')
- || (place[1] == '\0')) { /* found non-option */
- place = EMSG;
- if (IN_ORDER) {
- /*
- * GNU extension:
- * return non-option as argument to option 1
- */
- optarg = nargv[optind++];
- return INORDER;
- }
- if (!PERMUTE) {
- /*
- * if no permutation wanted, stop parsing
- * at first non-option
- */
- return -1;
- }
- /* do permutation */
- if (nonopt_start == -1)
- nonopt_start = optind;
- else if (nonopt_end != -1) {
- permute_args(nonopt_start, nonopt_end,
- optind, nargv);
- nonopt_start = optind -
- (nonopt_end - nonopt_start);
- nonopt_end = -1;
- }
- optind++;
- /* process next argument */
- goto start;
- }
- if (nonopt_start != -1 && nonopt_end == -1)
- nonopt_end = optind;
- if (place[1] && *++place == '-') { /* found "--" */
- place++;
- return -2;
- }
- }
- if ((optchar = (int)*place++) == (int)':' ||
- (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
- /* option letter unknown or ':' */
- if (!*place)
- ++optind;
- if (PRINT_ERROR)
- warnx(illoptchar, optchar);
- optopt = optchar;
- return BADCH;
- }
- if (optchar == 'W' && oli[1] == ';') { /* -W long-option */
- /* XXX: what if no long options provided (called by getopt)? */
- if (*place)
- return -2;
-
- if (++optind >= nargc) { /* no arg */
- place = EMSG;
- if (PRINT_ERROR)
- warnx(recargchar, optchar);
- optopt = optchar;
- return BADARG;
- } else /* white space */
- place = nargv[optind];
- /*
- * Handle -W arg the same as --arg (which causes getopt to
- * stop parsing).
- */
- return -2;
- }
- if (*++oli != ':') { /* doesn't take argument */
- if (!*place)
- ++optind;
- } else { /* takes (optional) argument */
- optarg = NULL;
- if (*place) /* no white space */
- optarg = (char *)place;
- /* XXX: disable test for :: if PC? (GNU doesn't) */
- else if (oli[1] != ':') { /* arg not optional */
- if (++optind >= nargc) { /* no arg */
- place = EMSG;
- if (PRINT_ERROR)
- warnx(recargchar, optchar);
- optopt = optchar;
- return BADARG;
- } else
- optarg = nargv[optind];
- }
- place = EMSG;
- ++optind;
- }
- /* dump back option letter */
- return optchar;
-}
-
-#ifdef REPLACE_GETOPT
-/*
- * getopt --
- * Parse argc/argv argument vector.
- *
- * [eventually this will replace the real getopt]
- */
-int
-getopt(nargc, nargv, options)
- int nargc;
- char * const *nargv;
- const char *options;
-{
- int retval;
-
- _DIAGASSERT(nargv != NULL);
- _DIAGASSERT(options != NULL);
-
- retval = getopt_internal(nargc, (char **)nargv, options);
- if (retval == -2) {
- ++optind;
- /*
- * We found an option (--), so if we skipped non-options,
- * we have to permute.
- */
- if (nonopt_end != -1) {
- permute_args(nonopt_start, nonopt_end, optind,
- (char **)nargv);
- optind -= nonopt_end - nonopt_start;
- }
- nonopt_start = nonopt_end = -1;
- retval = -1;
- }
- return retval;
-}
-#endif
-
-/*
- * getopt_long --
- * Parse argc/argv argument vector.
- */
-int
-getopt_long(nargc, nargv, options, long_options, idx)
- int nargc;
- char * const *nargv;
- const char *options;
- const struct option *long_options;
- int *idx;
-{
- int retval;
-
-#define IDENTICAL_INTERPRETATION(_x, _y) \
- (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
- long_options[(_x)].flag == long_options[(_y)].flag && \
- long_options[(_x)].val == long_options[(_y)].val)
-
- _DIAGASSERT(nargv != NULL);
- _DIAGASSERT(options != NULL);
- _DIAGASSERT(long_options != NULL);
- /* idx may be NULL */
-
- retval = getopt_internal(nargc, (char **)nargv, options);
- if (retval == -2) {
- char *current_argv, *has_equal;
- size_t current_argv_len;
- int i, ambiguous, match;
-
- current_argv = (char *)place;
- match = -1;
- ambiguous = 0;
-
- optind++;
- place = EMSG;
-
- if (*current_argv == '\0') { /* found "--" */
- /*
- * We found an option (--), so if we skipped
- * non-options, we have to permute.
- */
- if (nonopt_end != -1) {
- permute_args(nonopt_start, nonopt_end,
- optind, (char **)nargv);
- optind -= nonopt_end - nonopt_start;
- }
- nonopt_start = nonopt_end = -1;
- return -1;
- }
- if ((has_equal = strchr(current_argv, '=')) != NULL) {
- /* argument found (--option=arg) */
- current_argv_len = has_equal - current_argv;
- has_equal++;
- } else
- current_argv_len = strlen(current_argv);
-
- for (i = 0; long_options[i].name; i++) {
- /* find matching long option */
- if (strncmp(current_argv, long_options[i].name,
- current_argv_len))
- continue;
-
- if (strlen(long_options[i].name) ==
- (unsigned)current_argv_len) {
- /* exact match */
- match = i;
- ambiguous = 0;
- break;
- }
- if (match == -1) /* partial match */
- match = i;
- else if (!IDENTICAL_INTERPRETATION(i, match))
- ambiguous = 1;
- }
- if (ambiguous) {
- /* ambiguous abbreviation */
- if (PRINT_ERROR)
- warnx(ambig, (int)current_argv_len,
- current_argv);
- optopt = 0;
- return BADCH;
- }
- if (match != -1) { /* option found */
- if (long_options[match].has_arg == no_argument
- && has_equal) {
- if (PRINT_ERROR)
- warnx(noarg, (int)current_argv_len,
- current_argv);
- /*
- * XXX: GNU sets optopt to val regardless of
- * flag
- */
- if (long_options[match].flag == NULL)
- optopt = long_options[match].val;
- else
- optopt = 0;
- return BADARG;
- }
- if (long_options[match].has_arg == required_argument ||
- long_options[match].has_arg == optional_argument) {
- if (has_equal)
- optarg = has_equal;
- else if (long_options[match].has_arg ==
- required_argument) {
- /*
- * optional argument doesn't use
- * next nargv
- */
- optarg = nargv[optind++];
- }
- }
- if ((long_options[match].has_arg == required_argument)
- && (optarg == NULL)) {
- /*
- * Missing argument; leading ':'
- * indicates no error should be generated
- */
- if (PRINT_ERROR)
- warnx(recargstring, current_argv);
- /*
- * XXX: GNU sets optopt to val regardless
- * of flag
- */
- if (long_options[match].flag == NULL)
- optopt = long_options[match].val;
- else
- optopt = 0;
- --optind;
- return BADARG;
- }
- } else { /* unknown option */
- if (PRINT_ERROR)
- warnx(illoptstring, current_argv);
- optopt = 0;
- return BADCH;
- }
- if (long_options[match].flag) {
- *long_options[match].flag = long_options[match].val;
- retval = 0;
- } else
- retval = long_options[match].val;
- if (idx)
- *idx = match;
- }
- return retval;
-#undef IDENTICAL_INTERPRETATION
-}
diff --git a/libmagic/src/main/cpp/file/is_json.c b/libmagic/src/main/cpp/file/is_json.c
new file mode 100644
index 0000000..a8a6eca
--- /dev/null
+++ b/libmagic/src/main/cpp/file/is_json.c
@@ -0,0 +1,455 @@
+/*-
+ * Copyright (c) 2018 Christos Zoulas
+ * 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 THE NETBSD FOUNDATION, INC. AND 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 THE FOUNDATION OR 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.
+ */
+
+/*
+ * Parse JSON object serialization format (RFC-7159)
+ */
+
+#ifndef TEST
+#include "file.h"
+
+#ifndef lint
+FILE_RCSID("@(#)$File: is_json.c,v 1.12 2018/10/19 00:26:26 christos Exp $")
+#endif
+
+#include
+#include "magic.h"
+#endif
+
+#ifdef DEBUG
+#include
+#define DPRINTF(a, b, c) \
+ printf("%s [%.2x/%c] %.20s\n", (a), *(b), *(b), (const char *)(c))
+#else
+#define DPRINTF(a, b, c) do { } while (/*CONSTCOND*/0)
+#endif
+
+#define JSON_ARRAY 0
+#define JSON_CONSTANT 1
+#define JSON_NUMBER 2
+#define JSON_OBJECT 3
+#define JSON_STRING 4
+#define JSON_MAX 5
+
+/*
+ * if JSON_COUNT != 0:
+ * count all the objects, require that we have the whole data file
+ * otherwise:
+ * stop if we find an object or an array
+ */
+#ifndef JSON_COUNT
+#define JSON_COUNT 0
+#endif
+
+static int json_parse(const unsigned char **, const unsigned char *, size_t *,
+ size_t);
+
+static int
+json_isspace(const unsigned char uc)
+{
+ switch (uc) {
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+json_isdigit(unsigned char uc)
+{
+ switch (uc) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int
+json_isxdigit(unsigned char uc)
+{
+ if (json_isdigit(uc))
+ return 1;
+ switch (uc) {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static const unsigned char *
+json_skip_space(const unsigned char *uc, const unsigned char *ue)
+{
+ while (uc < ue && json_isspace(*uc))
+ uc++;
+ return uc;
+}
+
+static int
+json_parse_string(const unsigned char **ucp, const unsigned char *ue)
+{
+ const unsigned char *uc = *ucp;
+ size_t i;
+
+ DPRINTF("Parse string: ", uc, *ucp);
+ while (uc < ue) {
+ switch (*uc++) {
+ case '\0':
+ goto out;
+ case '\\':
+ if (uc == ue)
+ goto out;
+ switch (*uc++) {
+ case '\0':
+ goto out;
+ case '"':
+ case '\\':
+ case '/':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ continue;
+ case 'u':
+ if (ue - uc < 4) {
+ uc = ue;
+ goto out;
+ }
+ for (i = 0; i < 4; i++)
+ if (!json_isxdigit(*uc++))
+ goto out;
+ continue;
+ default:
+ goto out;
+ }
+ case '"':
+ *ucp = uc;
+ return 1;
+ default:
+ continue;
+ }
+ }
+out:
+ DPRINTF("Bad string: ", uc, *ucp);
+ *ucp = uc;
+ return 0;
+}
+
+static int
+json_parse_array(const unsigned char **ucp, const unsigned char *ue,
+ size_t *st, size_t lvl)
+{
+ const unsigned char *uc = *ucp;
+
+ DPRINTF("Parse array: ", uc, *ucp);
+ while (uc < ue) {
+ if (!json_parse(&uc, ue, st, lvl + 1))
+ goto out;
+ if (uc == ue)
+ goto out;
+ switch (*uc) {
+ case ',':
+ uc++;
+ continue;
+ case ']':
+ *ucp = uc + 1;
+ return 1;
+ default:
+ goto out;
+ }
+ }
+out:
+ DPRINTF("Bad array: ", uc, *ucp);
+ *ucp = uc;
+ return 0;
+}
+
+static int
+json_parse_object(const unsigned char **ucp, const unsigned char *ue,
+ size_t *st, size_t lvl)
+{
+ const unsigned char *uc = *ucp;
+ DPRINTF("Parse object: ", uc, *ucp);
+ while (uc < ue) {
+ uc = json_skip_space(uc, ue);
+ if (uc == ue)
+ goto out;
+ if (*uc++ != '"') {
+ DPRINTF("not string", uc, *ucp);
+ goto out;
+ }
+ DPRINTF("next field", uc, *ucp);
+ if (!json_parse_string(&uc, ue)) {
+ DPRINTF("not string", uc, *ucp);
+ goto out;
+ }
+ uc = json_skip_space(uc, ue);
+ if (uc == ue)
+ goto out;
+ if (*uc++ != ':') {
+ DPRINTF("not colon", uc, *ucp);
+ goto out;
+ }
+ if (!json_parse(&uc, ue, st, lvl + 1)) {
+ DPRINTF("not json", uc, *ucp);
+ goto out;
+ }
+ if (uc == ue)
+ goto out;
+ switch (*uc++) {
+ case ',':
+ continue;
+ case '}': /* { */
+ *ucp = uc;
+ DPRINTF("Good object: ", uc, *ucp);
+ return 1;
+ default:
+ *ucp = uc - 1;
+ DPRINTF("not more", uc, *ucp);
+ goto out;
+ }
+ }
+out:
+ DPRINTF("Bad object: ", uc, *ucp);
+ *ucp = uc;
+ return 0;
+}
+
+static int
+json_parse_number(const unsigned char **ucp, const unsigned char *ue)
+{
+ const unsigned char *uc = *ucp;
+ int got = 0;
+
+ DPRINTF("Parse number: ", uc, *ucp);
+ if (uc == ue)
+ return 0;
+ if (*uc == '-')
+ uc++;
+
+ for (; uc < ue; uc++) {
+ if (!json_isdigit(*uc))
+ break;
+ got = 1;
+ }
+ if (uc == ue)
+ goto out;
+ if (*uc == '.')
+ uc++;
+ for (; uc < ue; uc++) {
+ if (!json_isdigit(*uc))
+ break;
+ got = 1;
+ }
+ if (uc == ue)
+ goto out;
+ if (got && (*uc == 'e' || *uc == 'E')) {
+ uc++;
+ got = 0;
+ if (uc == ue)
+ goto out;
+ if (*uc == '+' || *uc == '-')
+ uc++;
+ for (; uc < ue; uc++) {
+ if (!json_isdigit(*uc))
+ break;
+ got = 1;
+ }
+ }
+out:
+ if (!got)
+ DPRINTF("Bad number: ", uc, *ucp);
+ else
+ DPRINTF("Good number: ", uc, *ucp);
+ *ucp = uc;
+ return got;
+}
+
+static int
+json_parse_const(const unsigned char **ucp, const unsigned char *ue,
+ const char *str, size_t len)
+{
+ const unsigned char *uc = *ucp;
+
+ DPRINTF("Parse const: ", uc, *ucp);
+ for (len--; uc < ue && --len;) {
+ if (*uc++ == *++str)
+ continue;
+ }
+ if (len)
+ DPRINTF("Bad const: ", uc, *ucp);
+ *ucp = uc;
+ return len == 0;
+}
+
+static int
+json_parse(const unsigned char **ucp, const unsigned char *ue,
+ size_t *st, size_t lvl)
+{
+ const unsigned char *uc;
+ int rv = 0;
+ int t;
+
+ uc = json_skip_space(*ucp, ue);
+ if (uc == ue)
+ goto out;
+
+ // Avoid recursion
+ if (lvl > 20)
+ return 0;
+#if JSON_COUNT
+ /* bail quickly if not counting */
+ if (lvl > 1 && (st[JSON_OBJECT] || st[JSON_ARRAY]))
+ return 1;
+#endif
+
+ DPRINTF("Parse general: ", uc, *ucp);
+ switch (*uc++) {
+ case '"':
+ rv = json_parse_string(&uc, ue);
+ t = JSON_STRING;
+ break;
+ case '[':
+ rv = json_parse_array(&uc, ue, st, lvl + 1);
+ t = JSON_ARRAY;
+ break;
+ case '{': /* '}' */
+ rv = json_parse_object(&uc, ue, st, lvl + 1);
+ t = JSON_OBJECT;
+ break;
+ case 't':
+ rv = json_parse_const(&uc, ue, "true", sizeof("true"));
+ t = JSON_CONSTANT;
+ break;
+ case 'f':
+ rv = json_parse_const(&uc, ue, "false", sizeof("false"));
+ t = JSON_CONSTANT;
+ break;
+ case 'n':
+ rv = json_parse_const(&uc, ue, "null", sizeof("null"));
+ t = JSON_CONSTANT;
+ break;
+ default:
+ --uc;
+ rv = json_parse_number(&uc, ue);
+ t = JSON_NUMBER;
+ break;
+ }
+ if (rv)
+ st[t]++;
+ uc = json_skip_space(uc, ue);
+out:
+ *ucp = uc;
+ DPRINTF("End general: ", uc, *ucp);
+ if (lvl == 0)
+ return rv && (st[JSON_ARRAY] || st[JSON_OBJECT]);
+ return rv;
+}
+
+#ifndef TEST
+int
+file_is_json(struct magic_set *ms, const struct buffer *b)
+{
+ const unsigned char *uc = CAST(const unsigned char *, b->fbuf);
+ const unsigned char *ue = uc + b->flen;
+ size_t st[JSON_MAX];
+ int mime = ms->flags & MAGIC_MIME;
+
+
+ if ((ms->flags & (MAGIC_APPLE|MAGIC_EXTENSION)) != 0)
+ return 0;
+
+ memset(st, 0, sizeof(st));
+
+ if (!json_parse(&uc, ue, st, 0))
+ return 0;
+
+ if (mime == MAGIC_MIME_ENCODING)
+ return 1;
+ if (mime) {
+ if (file_printf(ms, "application/json") == -1)
+ return -1;
+ return 1;
+ }
+ if (file_printf(ms, "JSON data") == -1)
+ return -1;
+#if JSON_COUNT
+#define P(n) st[n], st[n] > 1 ? "s" : ""
+ if (file_printf(ms, " (%" SIZE_T_FORMAT "u object%s, %" SIZE_T_FORMAT
+ "u array%s, %" SIZE_T_FORMAT "u string%s, %" SIZE_T_FORMAT
+ "u constant%s, %" SIZE_T_FORMAT "u number%s)", P(JSON_OBJECT),
+ P(JSON_ARRAY), P(JSON_STRING), P(JSON_CONSTANT), P(JSON_NUMBER))
+ == -1)
+ return -1;
+#endif
+ return 1;
+}
+
+#else
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+int
+main(int argc, char *argv[])
+{
+ int fd, rv;
+ struct stat st;
+ unsigned char *p;
+ size_t stats[JSON_MAX];
+
+ if ((fd = open(argv[1], O_RDONLY)) == -1)
+ err(EXIT_FAILURE, "Can't open `%s'", argv[1]);
+
+ if (fstat(fd, &st) == -1)
+ err(EXIT_FAILURE, "Can't stat `%s'", argv[1]);
+
+ if ((p = malloc(st.st_size)) == NULL)
+ err(EXIT_FAILURE, "Can't allocate %jd bytes",
+ (intmax_t)st.st_size);
+ if (read(fd, p, st.st_size) != st.st_size)
+ err(EXIT_FAILURE, "Can't read %jd bytes",
+ (intmax_t)st.st_size);
+ memset(stats, 0, sizeof(stats));
+ printf("is json %d\n", json_parse((const unsigned char **)&p,
+ p + st.st_size, stats, 0));
+ return 0;
+}
+#endif
diff --git a/libmagic/src/main/cpp/file/is_tar.c b/libmagic/src/main/cpp/file/is_tar.c
index 7110604..82b0805 100644
--- a/libmagic/src/main/cpp/file/is_tar.c
+++ b/libmagic/src/main/cpp/file/is_tar.c
@@ -40,7 +40,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: is_tar.c,v 1.41 2017/11/02 20:25:39 christos Exp $")
+FILE_RCSID("@(#)$File: is_tar.c,v 1.44 2019/02/20 02:35:27 christos Exp $")
#endif
#include "magic.h"
@@ -62,7 +62,7 @@ static const char tartype[][32] = { /* should be equal to messages */
protected int
file_is_tar(struct magic_set *ms, const struct buffer *b)
{
- const unsigned char *buf = b->fbuf;
+ const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
/*
* Do the tar test first, because if the first file in the tar
@@ -78,9 +78,13 @@ file_is_tar(struct magic_set *ms, const struct buffer *b)
if (tar < 1 || tar > 3)
return 0;
+ if (mime == MAGIC_MIME_ENCODING)
+ return 1;
+
if (file_printf(ms, "%s", mime ? "application/x-tar" :
tartype[tar - 1]) == -1)
return -1;
+
return 1;
}
@@ -94,7 +98,8 @@ file_is_tar(struct magic_set *ms, const struct buffer *b)
private int
is_tar(const unsigned char *buf, size_t nbytes)
{
- const union record *header = (const union record *)(const void *)buf;
+ const union record *header = RCAST(const union record *,
+ RCAST(const void *, buf));
size_t i;
int sum, recsum;
const unsigned char *p, *ep;
@@ -143,7 +148,7 @@ from_oct(const char *where, size_t digs)
if (digs == 0)
return -1;
- while (isspace((unsigned char)*where)) { /* Skip spaces */
+ while (isspace(CAST(unsigned char, *where))) { /* Skip spaces */
where++;
if (digs-- == 0)
return -1; /* All blank field */
@@ -154,7 +159,7 @@ from_oct(const char *where, size_t digs)
digs--;
}
- if (digs > 0 && *where && !isspace((unsigned char)*where))
+ if (digs > 0 && *where && !isspace(CAST(unsigned char, *where)))
return -1; /* Ended on non-(space/NUL) */
return value;
diff --git a/libmagic/src/main/cpp/file/localtime_r.c b/libmagic/src/main/cpp/file/localtime_r.c
deleted file mode 100644
index 35c3b40..0000000
--- a/libmagic/src/main/cpp/file/localtime_r.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $ */
-
-#include "file.h"
-#ifndef lint
-FILE_RCSID("@(#)$File: localtime_r.c,v 1.1 2015/01/09 19:28:32 christos Exp $")
-#endif /* lint */
-#include
-#include
-
-/* asctime_r is not thread-safe anyway */
-struct tm *
-localtime_r(const time_t *t, struct tm *tm)
-{
- struct tm *tmp = localtime(t);
- if (tmp == NULL)
- return NULL;
- memcpy(tm, tmp, sizeof(*tm));
- return tmp;
-}
diff --git a/libmagic/src/main/cpp/file/magic.c b/libmagic/src/main/cpp/file/magic.c
index 1448a69..2207f08 100644
--- a/libmagic/src/main/cpp/file/magic.c
+++ b/libmagic/src/main/cpp/file/magic.c
@@ -33,7 +33,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.109 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -44,9 +44,7 @@ FILE_RCSID("@(#)$File: magic.c,v 1.102 2017/08/28 13:39:18 christos Exp $")
#ifdef QUICK
#include
#endif
-#ifdef HAVE_LIMITS_H
#include /* for PIPE_BUF */
-#endif
#if defined(HAVE_UTIMES)
# include
@@ -314,7 +312,8 @@ magic_load_buffers(struct magic_set *ms, void **bufs, size_t *sizes,
{
if (ms == NULL)
return -1;
- return buffer_apprentice(ms, (struct magic **)bufs, sizes, nbufs);
+ return buffer_apprentice(ms, RCAST(struct magic **, bufs),
+ sizes, nbufs);
}
#endif
@@ -407,7 +406,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
struct stat sb;
ssize_t nbytes = 0; /* number of bytes read from a datafile */
int ispipe = 0;
- off_t pos = (off_t)-1;
+ off_t pos = CAST(off_t, -1);
if (file_reset(ms, 1) == -1)
goto out;
@@ -435,25 +434,13 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
if (fd == STDIN_FILENO)
_setmode(STDIN_FILENO, O_BINARY);
#endif
-
- if (inname == NULL) {
- if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
- ispipe = 1;
- else
- pos = lseek(fd, (off_t)0, SEEK_CUR);
- } else {
- int flags = O_RDONLY|O_BINARY;
- int okstat = stat(inname, &sb) == 0;
-
- if (okstat && S_ISFIFO(sb.st_mode)) {
-#ifdef O_NONBLOCK
- flags |= O_NONBLOCK;
-#endif
- ispipe = 1;
- }
-
+ if (inname != NULL) {
+ int flags = O_RDONLY|O_BINARY|O_NONBLOCK;
errno = 0;
if ((fd = open(inname, flags)) < 0) {
+ int okstat = stat(inname, &sb) == 0;
+ if (okstat && S_ISFIFO(sb.st_mode))
+ ispipe = 1;
#ifdef WIN32
/*
* Can't stat, can't open. It may have been opened in
@@ -472,12 +459,13 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
rv = 0;
goto done;
}
-#ifdef O_NONBLOCK
- if ((flags = fcntl(fd, F_GETFL)) != -1) {
- flags &= ~O_NONBLOCK;
- (void)fcntl(fd, F_SETFL, flags);
- }
-#endif
+ }
+
+ if (fd != -1) {
+ if (fstat(fd, &sb) == 0 && S_ISFIFO(sb.st_mode))
+ ispipe = 1;
+ if (inname == NULL)
+ pos = lseek(fd, CAST(off_t, 0), SEEK_CUR);
}
/*
@@ -486,8 +474,8 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
if (ispipe) {
ssize_t r = 0;
- while ((r = sread(fd, (void *)&buf[nbytes],
- (size_t)(ms->bytes_max - nbytes), 1)) > 0) {
+ while ((r = sread(fd, RCAST(void *, &buf[nbytes]),
+ CAST(size_t, ms->bytes_max - nbytes), 1)) > 0) {
nbytes += r;
if (r < PIPE_BUF) break;
}
@@ -507,7 +495,7 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
_isatty(fd) ? 8 * 1024 :
#endif
ms->bytes_max;
- if ((nbytes = read(fd, (char *)buf, howmany)) == -1) {
+ if ((nbytes = read(fd, RCAST(void *, buf), howmany)) == -1) {
if (inname == NULL && fd != STDIN_FILENO)
file_error(ms, errno, "cannot read fd %d", fd);
else
@@ -518,13 +506,13 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd)
}
(void)memset(buf + nbytes, 0, SLOP); /* NUL terminate */
- if (file_buffer(ms, fd, inname, buf, (size_t)nbytes) == -1)
+ if (file_buffer(ms, fd, inname, buf, CAST(size_t, nbytes)) == -1)
goto done;
rv = 0;
done:
free(buf);
if (fd != -1) {
- if (pos != (off_t)-1)
+ if (pos != CAST(off_t, -1))
(void)lseek(fd, pos, SEEK_SET);
close_and_restore(ms, inname, fd, &sb);
}
@@ -598,27 +586,29 @@ magic_version(void)
public int
magic_setparam(struct magic_set *ms, int param, const void *val)
{
+ if (ms == NULL)
+ return -1;
switch (param) {
case MAGIC_PARAM_INDIR_MAX:
- ms->indir_max = (uint16_t)*(const size_t *)val;
+ ms->indir_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_NAME_MAX:
- ms->name_max = (uint16_t)*(const size_t *)val;
+ ms->name_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_ELF_PHNUM_MAX:
- ms->elf_phnum_max = (uint16_t)*(const size_t *)val;
+ ms->elf_phnum_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_ELF_SHNUM_MAX:
- ms->elf_shnum_max = (uint16_t)*(const size_t *)val;
+ ms->elf_shnum_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_ELF_NOTES_MAX:
- ms->elf_notes_max = (uint16_t)*(const size_t *)val;
+ ms->elf_notes_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_REGEX_MAX:
- ms->elf_notes_max = (uint16_t)*(const size_t *)val;
+ ms->regex_max = CAST(uint16_t, *CAST(const size_t *, val));
return 0;
case MAGIC_PARAM_BYTES_MAX:
- ms->bytes_max = *(const size_t *)val;
+ ms->bytes_max = *CAST(const size_t *, val);
return 0;
default:
errno = EINVAL;
@@ -629,27 +619,29 @@ magic_setparam(struct magic_set *ms, int param, const void *val)
public int
magic_getparam(struct magic_set *ms, int param, void *val)
{
+ if (ms == NULL)
+ return -1;
switch (param) {
case MAGIC_PARAM_INDIR_MAX:
- *(size_t *)val = ms->indir_max;
+ *CAST(size_t *, val) = ms->indir_max;
return 0;
case MAGIC_PARAM_NAME_MAX:
- *(size_t *)val = ms->name_max;
+ *CAST(size_t *, val) = ms->name_max;
return 0;
case MAGIC_PARAM_ELF_PHNUM_MAX:
- *(size_t *)val = ms->elf_phnum_max;
+ *CAST(size_t *, val) = ms->elf_phnum_max;
return 0;
case MAGIC_PARAM_ELF_SHNUM_MAX:
- *(size_t *)val = ms->elf_shnum_max;
+ *CAST(size_t *, val) = ms->elf_shnum_max;
return 0;
case MAGIC_PARAM_ELF_NOTES_MAX:
- *(size_t *)val = ms->elf_notes_max;
+ *CAST(size_t *, val) = ms->elf_notes_max;
return 0;
case MAGIC_PARAM_REGEX_MAX:
- *(size_t *)val = ms->regex_max;
+ *CAST(size_t *, val) = ms->regex_max;
return 0;
case MAGIC_PARAM_BYTES_MAX:
- *(size_t *)val = ms->bytes_max;
+ *CAST(size_t *, val) = ms->bytes_max;
return 0;
default:
errno = EINVAL;
diff --git a/libmagic/src/main/cpp/file/magic.h b/libmagic/src/main/cpp/file/magic.h
index 2d707d5..ac8f8e1 100644
--- a/libmagic/src/main/cpp/file/magic.h
+++ b/libmagic/src/main/cpp/file/magic.h
@@ -58,6 +58,7 @@
#define MAGIC_NO_CHECK_CDF 0x0040000 /* Don't check for cdf files */
#define MAGIC_NO_CHECK_TOKENS 0x0100000 /* Don't check tokens */
#define MAGIC_NO_CHECK_ENCODING 0x0200000 /* Don't check text encodings */
+#define MAGIC_NO_CHECK_JSON 0x0400000 /* Don't check for JSON files */
/* No built-in tests; only consult the magic file */
#define MAGIC_NO_CHECK_BUILTIN ( \
@@ -70,6 +71,7 @@
MAGIC_NO_CHECK_CDF | \
MAGIC_NO_CHECK_TOKENS | \
MAGIC_NO_CHECK_ENCODING | \
+ MAGIC_NO_CHECK_JSON | \
0 \
)
@@ -96,7 +98,7 @@ b\22no_check_cdf\0\
b\23no_check_reserved0\0\
b\24no_check_tokens\0\
b\25no_check_encoding\0\
-b\26no_check_reserved1\0\
+b\26no_check_json\0\
b\27no_check_reserved2\0\
b\30extension\0\
b\31transp_compression\0\
@@ -109,7 +111,7 @@ b\31transp_compression\0\
#define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
-#define MAGIC_VERSION 532 /* This implementation */
+#define MAGIC_VERSION 536 /* This implementation */
#ifdef __cplusplus
diff --git a/libmagic/src/main/cpp/file/mygetopt.h b/libmagic/src/main/cpp/file/mygetopt.h
index ef87525..d766762 100644
--- a/libmagic/src/main/cpp/file/mygetopt.h
+++ b/libmagic/src/main/cpp/file/mygetopt.h
@@ -64,5 +64,5 @@ struct option {
int getopt_long(int, char * const *, const char *,
const struct option *, int *);
-
+
#endif /* !_GETOPT_H_ */
diff --git a/libmagic/src/main/cpp/file/print.c b/libmagic/src/main/cpp/file/print.c
index 4ffa445..6dad1de 100644
--- a/libmagic/src/main/cpp/file/print.c
+++ b/libmagic/src/main/cpp/file/print.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 THE AUTHOR AND 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
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: print.c,v 1.81 2016/01/19 15:09:03 christos Exp $")
+FILE_RCSID("@(#)$File: print.c,v 1.84 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include
@@ -65,7 +65,7 @@ file_mdump(struct magic *m)
if (m->in_op & FILE_OPINVERSE)
(void) fputc('~', stderr);
(void) fprintf(stderr, "%c%u),",
- ((size_t)(m->in_op & FILE_OPS_MASK) <
+ (CAST(size_t, m->in_op & FILE_OPS_MASK) <
SZOF(optyp)) ? optyp[m->in_op & FILE_OPS_MASK] : '?',
m->in_offset);
}
@@ -78,16 +78,16 @@ file_mdump(struct magic *m)
if (IS_STRING(m->type)) {
if (m->str_flags) {
(void) fputc('/', stderr);
- if (m->str_flags & STRING_COMPACT_WHITESPACE)
+ if (m->str_flags & STRING_COMPACT_WHITESPACE)
(void) fputc(CHAR_COMPACT_WHITESPACE, stderr);
- if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE)
+ if (m->str_flags & STRING_COMPACT_OPTIONAL_WHITESPACE)
(void) fputc(CHAR_COMPACT_OPTIONAL_WHITESPACE,
stderr);
- if (m->str_flags & STRING_IGNORE_LOWERCASE)
+ if (m->str_flags & STRING_IGNORE_LOWERCASE)
(void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
- if (m->str_flags & STRING_IGNORE_UPPERCASE)
+ if (m->str_flags & STRING_IGNORE_UPPERCASE)
(void) fputc(CHAR_IGNORE_UPPERCASE, stderr);
- if (m->str_flags & REGEX_OFFSET_START)
+ if (m->str_flags & REGEX_OFFSET_START)
(void) fputc(CHAR_REGEX_OFFSET_START, stderr);
if (m->str_flags & STRING_TEXTTEST)
(void) fputc(CHAR_TEXTTEST, stderr);
@@ -112,14 +112,14 @@ file_mdump(struct magic *m)
(void) fprintf(stderr, "/%u", m->str_range);
}
else {
- if ((size_t)(m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
+ if (CAST(size_t, m->mask_op & FILE_OPS_MASK) < SZOF(optyp))
(void) fputc(optyp[m->mask_op & FILE_OPS_MASK], stderr);
else
(void) fputc('?', stderr);
-
+
if (m->num_mask) {
(void) fprintf(stderr, "%.8llx",
- (unsigned long long)m->num_mask);
+ CAST(unsigned long long, m->num_mask));
}
}
(void) fprintf(stderr, ",%c", m->reln);
@@ -141,7 +141,7 @@ file_mdump(struct magic *m)
case FILE_LEQUAD:
case FILE_QUAD:
(void) fprintf(stderr, "%" INT64_T_FORMAT "d",
- (unsigned long long)m->value.q);
+ CAST(long long, m->value.q));
break;
case FILE_PSTRING:
case FILE_STRING:
@@ -149,7 +149,8 @@ file_mdump(struct magic *m)
case FILE_BESTRING16:
case FILE_LESTRING16:
case FILE_SEARCH:
- file_showstr(stderr, m->value.s, (size_t)m->vallen);
+ file_showstr(stderr, m->value.s,
+ CAST(size_t, m->vallen));
break;
case FILE_DATE:
case FILE_LEDATE:
@@ -217,11 +218,11 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
va_list va;
/* cuz we use stdout for most, stderr here */
- (void) fflush(stdout);
+ (void) fflush(stdout);
if (ms->file)
(void) fprintf(stderr, "%s, %lu: ", ms->file,
- (unsigned long)ms->line);
+ CAST(unsigned long, ms->line));
(void) fprintf(stderr, "Warning: ");
va_start(va, f);
(void) vfprintf(stderr, f, va);
@@ -243,7 +244,7 @@ file_fmttime(uint64_t v, int flags, char *buf)
} else {
// XXX: perhaps detect and print something if overflow
// on 32 bit time_t?
- t = (time_t)v;
+ t = CAST(time_t, v);
}
if (flags & FILE_T_LOCAL) {
diff --git a/libmagic/src/main/cpp/file/readcdf.c b/libmagic/src/main/cpp/file/readcdf.c
index 4b86e6f..5fa98e8 100644
--- a/libmagic/src/main/cpp/file/readcdf.c
+++ b/libmagic/src/main/cpp/file/readcdf.c
@@ -26,7 +26,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.67 2018/04/15 19:57:07 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.72 2019/02/20 02:35:27 christos Exp $")
#endif
#include
@@ -204,7 +204,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
&& len--; s += k) {
if (*s == '\0')
break;
- if (isprint((unsigned char)*s))
+ if (isprint(CAST(unsigned char, *s)))
vbuf[j++] = *s;
}
if (j == sizeof(vbuf))
@@ -252,7 +252,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
return -1;
}
}
- if (!NOTMIME(ms)) {
+ if (ms->flags & MAGIC_MIME_TYPE) {
if (str == NULL)
return 0;
if (file_printf(ms, "application/%s", str) == -1)
@@ -285,7 +285,7 @@ cdf_file_catalog(struct magic_set *ms, const cdf_header_t *h,
return -1;
}
free(cat);
- } else {
+ } else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/CDFV2") == -1)
return -1;
}
@@ -318,19 +318,19 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
case 2:
if (file_printf(ms, ", Os: Windows, Version %d.%d",
si.si_os_version & 0xff,
- (uint32_t)si.si_os_version >> 8) == -1)
+ CAST(uint32_t, si.si_os_version) >> 8) == -1)
return -2;
break;
case 1:
if (file_printf(ms, ", Os: MacOS, Version %d.%d",
- (uint32_t)si.si_os_version >> 8,
+ CAST(uint32_t, si.si_os_version) >> 8,
si.si_os_version & 0xff) == -1)
return -2;
break;
default:
if (file_printf(ms, ", Os %d, Version: %d.%d", si.si_os,
si.si_os_version & 0xff,
- (uint32_t)si.si_os_version >> 8) == -1)
+ CAST(uint32_t, si.si_os_version) >> 8) == -1)
return -2;
break;
}
@@ -353,11 +353,11 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_header_t *h,
#ifdef notdef
private char *
format_clsid(char *buf, size_t len, const uint64_t uuid[2]) {
- snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
+ snprintf(buf, len, "%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4"
PRIx64 "-%.12" PRIx64,
(uuid[0] >> 32) & (uint64_t)0x000000000ffffffffULL,
(uuid[0] >> 16) & (uint64_t)0x0000000000000ffffULL,
- (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
+ (uuid[0] >> 0) & (uint64_t)0x0000000000000ffffULL,
(uuid[1] >> 48) & (uint64_t)0x0000000000000ffffULL,
(uuid[1] >> 0) & (uint64_t)0x0000fffffffffffffULL);
return buf;
@@ -406,7 +406,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
for (j = 0; str == NULL && j < dir->dir_len; j++) {
d = &dir->dir_tab[j];
for (k = 0; k < sizeof(name); k++)
- name[k] = (char)cdf_tole2(d->d_name[k]);
+ name[k] = CAST(char, cdf_tole2(d->d_name[k]));
str = cdf_app_to_mime(name,
NOTMIME(ms) ? name2desc : name2mime);
}
@@ -416,7 +416,7 @@ cdf_check_summary_info(struct magic_set *ms, const cdf_info_t *info,
return -1;
i = 1;
}
- } else {
+ } else if (ms->flags & MAGIC_MIME_TYPE) {
if (str == NULL)
str = "vnd.ms-office";
if (file_printf(ms, "application/%s", str) == -1)
@@ -436,7 +436,7 @@ private struct sinfo {
const char *sections[5];
const int types[5];
} sectioninfo[] = {
- { "Encrypted", "encrypted",
+ { "Encrypted", "encrypted",
{
"EncryptedPackage", "EncryptedSummary",
NULL, NULL, NULL,
@@ -448,7 +448,7 @@ private struct sinfo {
},
},
- { "QuickBooks", "quickbooks",
+ { "QuickBooks", "quickbooks",
{
#if 0
"TaxForms", "PDFTaxForms", "modulesInBackup",
@@ -527,7 +527,7 @@ cdf_file_dir_info(struct magic_set *ms, const cdf_dir_t *dir)
if (NOTMIME(ms)) {
if (file_printf(ms, "CDFV2 %s", si->name) == -1)
return -1;
- } else {
+ } else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/%s", si->mime) == -1)
return -1;
}
@@ -540,7 +540,7 @@ protected int
file_trycdf(struct magic_set *ms, const struct buffer *b)
{
int fd = b->fd;
- const unsigned char *buf = b->fbuf;
+ const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
cdf_info_t info;
cdf_header_t h;
@@ -614,7 +614,7 @@ file_trycdf(struct magic_set *ms, const struct buffer *b)
if (file_printf(ms,
"Hangul (Korean) Word Processor File 5.x") == -1)
return -1;
- } else {
+ } else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/x-hwp") == -1)
return -1;
}
@@ -661,19 +661,20 @@ file_trycdf(struct magic_set *ms, const struct buffer *b)
out1:
free(sat.sat_tab);
out0:
- if (i == -1) {
- if (NOTMIME(ms)) {
+ /* If we handled it already, return */
+ if (i != -1)
+ return i;
+ /* Provide a default handler */
+ if (NOTMIME(ms)) {
if (file_printf(ms,
"Composite Document File V2 Document") == -1)
- return -1;
- if (*expn)
- if (file_printf(ms, ", %s", expn) == -1)
return -1;
- } else {
+ if (*expn)
+ if (file_printf(ms, ", %s", expn) == -1)
+ return -1;
+ } else if (ms->flags & MAGIC_MIME_TYPE) {
if (file_printf(ms, "application/CDFV2") == -1)
- return -1;
- }
- i = 1;
+ return -1;
}
- return i;
+ return 1;
}
diff --git a/libmagic/src/main/cpp/file/readelf.c b/libmagic/src/main/cpp/file/readelf.c
index db0b35a..db43c6c 100644
--- a/libmagic/src/main/cpp/file/readelf.c
+++ b/libmagic/src/main/cpp/file/readelf.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) Christos Zoulas 2003.
* All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -11,7 +11,7 @@
* 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 THE AUTHOR AND 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
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.144 2018/07/08 23:37:33 christos Exp $")
+FILE_RCSID("@(#)$File: readelf.c,v 1.162 2019/02/20 02:35:27 christos Exp $")
#endif
#ifdef BUILTIN_ELF
@@ -69,7 +69,7 @@ toomany(struct magic_set *ms, const char *name, uint16_t num)
{
if (file_printf(ms, ", too many %s (%u)", name, num) == -1)
return -1;
- return 0;
+ return 1;
}
private uint16_t
@@ -85,7 +85,7 @@ getu16(int swap, uint16_t value)
retval.c[0] = tmpval.c[1];
retval.c[1] = tmpval.c[0];
-
+
return retval.ui;
} else
return value;
@@ -106,7 +106,7 @@ getu32(int swap, uint32_t value)
retval.c[1] = tmpval.c[2];
retval.c[2] = tmpval.c[1];
retval.c[3] = tmpval.c[0];
-
+
return retval.ui;
} else
return value;
@@ -131,7 +131,7 @@ getu64(int swap, uint64_t value)
retval.c[5] = tmpval.c[2];
retval.c[6] = tmpval.c[1];
retval.c[7] = tmpval.c[0];
-
+
return retval.ui;
} else
return value;
@@ -262,7 +262,10 @@ static const size_t prpsoffsets32[] = {
84, /* SunOS 5.x (short name) */
44, /* Linux (command line) */
- 28, /* Linux 2.0.36 (short name) */
+ 28, /* Linux (short name) */
+
+ 48, /* Linux PowerPC (command line) */
+ 32, /* Linux PowerPC (short name) */
8, /* FreeBSD */
};
@@ -352,6 +355,11 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
off_t ph_off = off;
int ph_num = num;
+ if (num == 0) {
+ if (file_printf(ms, ", no program header") == -1)
+ return -1;
+ return 0;
+ }
if (size != xph_sizeof) {
if (file_printf(ms, ", corrupted program header size") == -1)
return -1;
@@ -388,9 +396,9 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
}
offset = 0;
for (;;) {
- if (offset >= (size_t)bufsize)
+ if (offset >= CAST(size_t, bufsize))
break;
- offset = donote(ms, nbuf, offset, (size_t)bufsize,
+ offset = donote(ms, nbuf, offset, CAST(size_t, bufsize),
clazz, swap, 4, flags, notecount, fd, ph_off,
ph_num, fsize);
if (offset == 0)
@@ -461,25 +469,25 @@ do_note_freebsd_version(struct magic_set *ms, int swap, void *v)
* Contents is __FreeBSD_version, whose relation to OS
* versions is defined by a huge table in the Porter's
* Handbook. This is the general scheme:
- *
+ *
* Releases:
* Mmp000 (before 4.10)
* Mmi0p0 (before 5.0)
* Mmm0p0
- *
+ *
* Development branches:
* Mmpxxx (before 4.6)
* Mmp1xx (before 4.10)
* Mmi1xx (before 5.0)
* M000xx (pre-M.0)
* Mmm1xx
- *
+ *
* M = major version
* m = minor version
* i = minor version increment (491000 -> 4.10)
* p = patchlevel
* x = revision
- *
+ *
* The first release of FreeBSD to use ELF by default
* was version 3.0.
*/
@@ -528,7 +536,7 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int swap __attribute__((__unused__)), uint32_t namesz, uint32_t descsz,
size_t noff, size_t doff, int *flags)
{
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
+ if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "GNU") == 0 &&
type == NT_GNU_BUILD_ID && (descsz >= 4 && descsz <= 20)) {
uint8_t desc[20];
const char *btype;
@@ -556,11 +564,11 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
return 1;
return 1;
}
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "Go") == 0 &&
+ if (namesz == 4 && strcmp(RCAST(char *, &nbuf[noff]), "Go") == 0 &&
type == NT_GO_BUILD_ID && descsz < 128) {
- if (file_printf(ms, ", Go BuildID=%s",
- (char *)&nbuf[doff]) == -1)
- return 1;
+ if (file_printf(ms, ", Go BuildID=%.*s",
+ CAST(int, descsz), RCAST(char *, &nbuf[doff])) == -1)
+ return -1;
return 1;
}
return 0;
@@ -571,14 +579,18 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int swap, uint32_t namesz, uint32_t descsz,
size_t noff, size_t doff, int *flags)
{
- if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
- type == NT_GNU_VERSION && descsz == 2) {
- *flags |= FLAGS_DID_OS_NOTE;
- file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]);
+ const char *name = RCAST(const char *, &nbuf[noff]);
+
+ if (namesz == 5 && strcmp(name, "SuSE") == 0 &&
+ type == NT_GNU_VERSION && descsz == 2) {
+ *flags |= FLAGS_DID_OS_NOTE;
+ if (file_printf(ms, ", for SuSE %d.%d", nbuf[doff],
+ nbuf[doff + 1]) == -1)
+ return -1;
return 1;
}
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
+ if (namesz == 4 && strcmp(name, "GNU") == 0 &&
type == NT_GNU_VERSION && descsz == 16) {
uint32_t desc[4];
memcpy(desc, &nbuf[doff], sizeof(desc));
@@ -609,7 +621,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
break;
default:
if (file_printf(ms, "") == -1)
- return 1;
+ return 1;
}
if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
@@ -617,7 +629,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
return 1;
}
- if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0) {
+ if (namesz == 7 && strcmp(name, "NetBSD") == 0) {
if (type == NT_NETBSD_VERSION && descsz == 4) {
*flags |= FLAGS_DID_OS_NOTE;
do_note_netbsd_version(ms, swap, &nbuf[doff]);
@@ -625,7 +637,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
}
}
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0) {
+ if (namesz == 8 && strcmp(name, "FreeBSD") == 0) {
if (type == NT_FREEBSD_VERSION && descsz == 4) {
*flags |= FLAGS_DID_OS_NOTE;
do_note_freebsd_version(ms, swap, &nbuf[doff]);
@@ -633,7 +645,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
}
}
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
+ if (namesz == 8 && strcmp(name, "OpenBSD") == 0 &&
type == NT_OPENBSD_VERSION && descsz == 4) {
*flags |= FLAGS_DID_OS_NOTE;
if (file_printf(ms, ", for OpenBSD") == -1)
@@ -642,7 +654,7 @@ do_os_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
return 1;
}
- if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
+ if (namesz == 10 && strcmp(name, "DragonFly") == 0 &&
type == NT_DRAGONFLY_VERSION && descsz == 4) {
uint32_t desc;
*flags |= FLAGS_DID_OS_NOTE;
@@ -663,7 +675,9 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
int swap, uint32_t namesz, uint32_t descsz,
size_t noff, size_t doff, int *flags)
{
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "PaX") == 0 &&
+ const char *name = RCAST(const char *, &nbuf[noff]);
+
+ if (namesz == 4 && strcmp(name, "PaX") == 0 &&
type == NT_NETBSD_PAX && descsz == 4) {
static const char *pax[] = {
"+mprotect",
@@ -685,7 +699,7 @@ do_pax_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
return 1;
for (i = 0; i < __arraycount(pax); i++) {
- if (((1 << (int)i) & desc) == 0)
+ if (((1 << CAST(int, i)) & desc) == 0)
continue;
if (file_printf(ms, "%s%s", did++ ? "," : "",
pax[i]) == -1)
@@ -702,6 +716,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
size_t noff, size_t doff, int *flags, size_t size, int clazz)
{
#ifdef ELFCORE
+ const char *name = RCAST(const char *, &nbuf[noff]);
+
int os_style = -1;
/*
* Sigh. The 2.0.36 kernel in Debian 2.1, at
@@ -717,16 +733,16 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
* doesn't include the terminating null in the
* name....
*/
- if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
- (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
+ if ((namesz == 4 && strncmp(name, "CORE", 4) == 0) ||
+ (namesz == 5 && strcmp(name, "CORE") == 0)) {
os_style = OS_STYLE_SVR4;
- }
+ }
- if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
+ if ((namesz == 8 && strcmp(name, "FreeBSD") == 0)) {
os_style = OS_STYLE_FREEBSD;
}
- if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
+ if ((namesz >= 11 && strncmp(name, "NetBSD-CORE", 11)
== 0)) {
os_style = OS_STYLE_NETBSD;
}
@@ -745,17 +761,17 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
char sbuf[512];
struct NetBSD_elfcore_procinfo pi;
memset(&pi, 0, sizeof(pi));
- memcpy(&pi, nbuf + doff, descsz);
+ memcpy(&pi, nbuf + doff, MIN(descsz, sizeof(pi)));
if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, "
"gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)",
file_printable(sbuf, sizeof(sbuf),
- CAST(char *, pi.cpi_name)),
- elf_getu32(swap, (uint32_t)pi.cpi_pid),
+ RCAST(char *, pi.cpi_name), sizeof(pi.cpi_name)),
+ elf_getu32(swap, CAST(uint32_t, pi.cpi_pid)),
elf_getu32(swap, pi.cpi_euid),
elf_getu32(swap, pi.cpi_egid),
elf_getu32(swap, pi.cpi_nlwps),
- elf_getu32(swap, (uint32_t)pi.cpi_siglwp),
+ elf_getu32(swap, CAST(uint32_t, pi.cpi_siglwp)),
elf_getu32(swap, pi.cpi_signo),
elf_getu32(swap, pi.cpi_sigcode)) == -1)
return 1;
@@ -765,6 +781,28 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
}
break;
+ case OS_STYLE_FREEBSD:
+ if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
+ size_t argoff, pidoff;
+
+ if (clazz == ELFCLASS32)
+ argoff = 4 + 4 + 17;
+ else
+ argoff = 4 + 4 + 8 + 17;
+ if (file_printf(ms, ", from '%.80s'", nbuf + doff +
+ argoff) == -1)
+ return 1;
+ pidoff = argoff + 81 + 2;
+ if (doff + pidoff + 4 <= size) {
+ if (file_printf(ms, ", pid=%u",
+ elf_getu32(swap, *RCAST(uint32_t *, (nbuf +
+ doff + pidoff)))) == -1)
+ return 1;
+ }
+ *flags |= FLAGS_DID_CORE;
+ }
+ break;
+
default:
if (type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
size_t i, j;
@@ -847,8 +885,8 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
i = k;
}
- cname = (unsigned char *)
- &nbuf[doff + prpsoffsets(i)];
+ cname = CAST(unsigned char *,
+ &nbuf[doff + prpsoffsets(i)]);
for (cp = cname; cp < nbuf + size && *cp
&& isprint(*cp); cp++)
continue;
@@ -859,7 +897,7 @@ do_core_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
while (cp > cname && isspace(cp[-1]))
cp--;
if (file_printf(ms, ", from '%.*s'",
- (int)(cp - cname), cname) == -1)
+ CAST(int, cp - cname), cname) == -1)
return 1;
*flags |= FLAGS_DID_CORE;
return 1;
@@ -886,7 +924,8 @@ get_offset_from_virtaddr(struct magic_set *ms, int swap, int clazz, int fd,
* virtual address in which the "virtaddr" belongs to.
*/
for ( ; num; num--) {
- if (pread(fd, xph_addr, xph_sizeof, off) < (ssize_t)xph_sizeof) {
+ if (pread(fd, xph_addr, xph_sizeof, off) <
+ CAST(ssize_t, xph_sizeof)) {
file_badread(ms);
return -1;
}
@@ -916,7 +955,8 @@ get_string_on_virtaddr(struct magic_set *ms,
offset = get_offset_from_virtaddr(ms, swap, clazz, fd, ph_off, ph_num,
fsize, virtaddr);
- if ((buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) {
+ if (offset < 0 ||
+ (buflen = pread(fd, buf, CAST(size_t, buflen), offset)) <= 0) {
file_badread(ms);
return 0;
}
@@ -925,7 +965,7 @@ get_string_on_virtaddr(struct magic_set *ms,
/* We expect only printable characters, so return if buffer contains
* non-printable character before the '\0' or just '\0'. */
- for (bptr = buf; *bptr && isprint((unsigned char)*bptr); bptr++)
+ for (bptr = buf; *bptr && isprint(CAST(unsigned char, *bptr)); bptr++)
continue;
if (*bptr != '\0')
return 0;
@@ -1027,12 +1067,12 @@ do_auxv_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
if (buflen == 0)
continue;
-
+
if (file_printf(ms, ", %s: '%s'", tag, buf) == -1)
return 0;
} else {
- if (file_printf(ms, ", %s: %d", tag, (int) xauxv_val)
- == -1)
+ if (file_printf(ms, ", %s: %d", tag,
+ CAST(int, xauxv_val)) == -1)
return 0;
}
}
@@ -1062,7 +1102,7 @@ dodynamic(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
switch (xdh_tag) {
case DT_FLAGS_1:
- if (xdh_val == DF_1_PIE)
+ if (xdh_val & DF_1_PIE)
ms->mode |= 0111;
else
ms->mode &= ~0111;
@@ -1110,14 +1150,16 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
}
if (namesz & 0x80000000) {
- file_printf(ms, ", bad note name size %#lx",
- CAST(unsigned long, namesz));
+ if (file_printf(ms, ", bad note name size %#lx",
+ CAST(unsigned long, namesz)) == -1)
+ return 0;
return 0;
}
if (descsz & 0x80000000) {
- file_printf(ms, ", bad note description size %#lx",
- CAST(unsigned long, descsz));
+ if (file_printf(ms, ", bad note description size %#lx",
+ CAST(unsigned long, descsz)) == -1)
+ return 0;
return 0;
}
@@ -1151,7 +1193,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
namesz, descsz, noff, doff, flags))
return offset;
}
-
+
if ((*flags & FLAGS_DID_NETBSD_PAX) == 0) {
if (do_pax_note(ms, nbuf, xnh_type, swap,
namesz, descsz, noff, doff, flags))
@@ -1171,7 +1213,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
return offset;
}
- if (namesz == 7 && strcmp(CAST(char *, &nbuf[noff]), "NetBSD") == 0) {
+ if (namesz == 7 && strcmp(RCAST(char *, &nbuf[noff]), "NetBSD") == 0) {
int descw, flag;
const char *str, *tag;
if (descsz > 100)
@@ -1202,7 +1244,7 @@ donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
if (*flags & flag)
return offset;
- str = CAST(const char *, &nbuf[doff]);
+ str = RCAST(const char *, &nbuf[doff]);
descw = CAST(int, descsz);
*flags |= flag;
file_printf(ms, ", %s: %.*s", tag, descw, str);
@@ -1278,6 +1320,11 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
char name[50];
ssize_t namesize;
+ if (num == 0) {
+ if (file_printf(ms, ", no section header") == -1)
+ return -1;
+ return 0;
+ }
if (size != xsh_sizeof) {
if (file_printf(ms, ", corrupted section header size") == -1)
return -1;
@@ -1343,7 +1390,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
CAST(uintmax_t, xsh_size),
CAST(uintmax_t, fsize)) == -1)
return -1;
- return 0;
+ return 0;
}
if ((nbuf = malloc(xsh_size)) == NULL) {
file_error(ms, errno, "Cannot allocate memory"
@@ -1428,7 +1475,7 @@ doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
return -1;
break;
}
- // gnu attributes
+ // gnu attributes
#endif
break;
}
@@ -1548,7 +1595,12 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
char interp[BUFSIZ];
ssize_t bufsize;
size_t offset, align, len;
-
+
+ if (num == 0) {
+ if (file_printf(ms, ", no program header") == -1)
+ return -1;
+ return 0;
+ }
if (size != xph_sizeof) {
if (file_printf(ms, ", corrupted program header size") == -1)
return -1;
@@ -1558,7 +1610,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
interp[0] = '\0';
for ( ; num; num--) {
int doread;
- if (pread(fd, xph_addr, xph_sizeof, off) <
+ if (pread(fd, xph_addr, xph_sizeof, off) <
CAST(ssize_t, xph_sizeof)) {
file_badread(ms);
return -1;
@@ -1579,7 +1631,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
continue;
if (((align = xph_align) & 0x80000000UL) != 0 ||
align < 4) {
- if (file_printf(ms,
+ if (file_printf(ms,
", invalid note alignment %#lx",
CAST(unsigned long, align)) == -1)
return -1;
@@ -1613,8 +1665,10 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
switch (xph_type) {
case PT_DYNAMIC:
offset = 0;
+ // Let DF_1 determine if we are PIE or not.
+ ms->mode &= ~0111;
for (;;) {
- if (offset >= (size_t)bufsize)
+ if (offset >= CAST(size_t, bufsize))
break;
offset = dodynamic(ms, nbuf, offset,
CAST(size_t, bufsize), clazz, swap);
@@ -1626,7 +1680,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
case PT_INTERP:
if (bufsize && nbuf[0]) {
nbuf[bufsize - 1] = '\0';
- memcpy(interp, nbuf, bufsize);
+ memcpy(interp, nbuf, CAST(size_t, bufsize));
} else
strlcpy(interp, "*empty*", sizeof(interp));
break;
@@ -1637,7 +1691,7 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
*/
offset = 0;
for (;;) {
- if (offset >= (size_t)bufsize)
+ if (offset >= CAST(size_t, bufsize))
break;
offset = donote(ms, nbuf, offset,
CAST(size_t, bufsize), clazz, swap, align,
@@ -1655,7 +1709,8 @@ dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
return -1;
if (interp[0])
if (file_printf(ms, ", interpreter %s",
- file_printable(ibuf, sizeof(ibuf), interp)) == -1)
+ file_printable(ibuf, sizeof(ibuf), interp, sizeof(interp)))
+ == -1)
return -1;
return 0;
}
@@ -1665,7 +1720,7 @@ protected int
file_tryelf(struct magic_set *ms, const struct buffer *b)
{
int fd = b->fd;
- const unsigned char *buf = b->fbuf;
+ const unsigned char *buf = CAST(const unsigned char *, b->fbuf);
size_t nbytes = b->flen;
union {
int32_t l;
@@ -1687,7 +1742,8 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
* file locations and thus file(1) cannot determine it from easily.
* Instead we traverse thru all section headers until a symbol table
* one is found or else the binary is stripped.
- * Return immediately if it's not ELF (so we avoid pipe2file unless needed).
+ * Return immediately if it's not ELF (so we avoid pipe2file unless
+ * needed).
*/
if (buf[EI_MAG0] != ELFMAG0
|| (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
@@ -1701,7 +1757,7 @@ file_tryelf(struct magic_set *ms, const struct buffer *b)
&& (errno == ESPIPE))
fd = file_pipe2file(ms, fd, buf, nbytes);
- if (fstat(fd, &st) == -1) {
+ if (fd == -1 || fstat(fd, &st) == -1) {
file_badread(ms);
return -1;
}
diff --git a/libmagic/src/main/cpp/file/readelf.h b/libmagic/src/main/cpp/file/readelf.h
index 6ae63f2..809d3f7 100644
--- a/libmagic/src/main/cpp/file/readelf.h
+++ b/libmagic/src/main/cpp/file/readelf.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) Christos Zoulas 2003.
* All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -11,7 +11,7 @@
* 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 THE AUTHOR AND 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
@@ -304,7 +304,7 @@ typedef struct {
#define GNU_OS_KNETBSD 4
/*
- * GNU Hardware capability information
+ * GNU Hardware capability information
* word[0]: Number of entries
* word[1]: Bitmask of enabled entries
* Followed by a byte id, and a NUL terminated string per entry
@@ -313,7 +313,7 @@ typedef struct {
/*
* GNU Build ID generated by ld
- * 160 bit SHA1 [default]
+ * 160 bit SHA1 [default]
* 128 bit md5 or uuid
*/
#define NT_GNU_BUILD_ID 3
diff --git a/libmagic/src/main/cpp/file/seccomp.c b/libmagic/src/main/cpp/file/seccomp.c
index a5abb4a..e7829ff 100644
--- a/libmagic/src/main/cpp/file/seccomp.c
+++ b/libmagic/src/main/cpp/file/seccomp.c
@@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: seccomp.c,v 1.6 2018/06/26 20:29:29 christos Exp $")
+FILE_RCSID("@(#)$File: seccomp.c,v 1.7 2018/09/09 20:33:28 christos Exp $")
#endif /* lint */
#if HAVE_LIBSECCOMP
@@ -126,14 +126,14 @@ enable_sandbox_basic(void)
DENY_RULE (socket);
// ...
-
+
// applying filter...
if (seccomp_load (ctx) == -1)
goto out;
// free ctx after the filter has been loaded into the kernel
seccomp_release(ctx);
return 0;
-
+
out:
seccomp_release(ctx);
return -1;
@@ -151,7 +151,7 @@ enable_sandbox_full(void)
if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == -1)
return -1;
-
+
// initialize the filter
ctx = seccomp_init(SCMP_ACT_KILL);
if (ctx == NULL)
@@ -163,10 +163,10 @@ enable_sandbox_full(void)
ALLOW_RULE(dup2);
ALLOW_RULE(exit);
ALLOW_RULE(exit_group);
- ALLOW_RULE(fcntl);
- ALLOW_RULE(fcntl64);
+ ALLOW_RULE(fcntl);
+ ALLOW_RULE(fcntl64);
ALLOW_RULE(fstat);
- ALLOW_RULE(fstat64);
+ ALLOW_RULE(fstat64);
ALLOW_RULE(getdents);
#ifdef __NR_getdents64
ALLOW_RULE(getdents64);
diff --git a/libmagic/src/main/cpp/file/softmagic.c b/libmagic/src/main/cpp/file/softmagic.c
index 9a5db9d..cfc1781 100644
--- a/libmagic/src/main/cpp/file/softmagic.c
+++ b/libmagic/src/main/cpp/file/softmagic.c
@@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: softmagic.c,v 1.262 2018/06/22 20:39:50 christos Exp $")
+FILE_RCSID("@(#)$File: softmagic.c,v 1.278 2019/02/20 02:35:27 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -45,11 +45,11 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.262 2018/06/22 20:39:50 christos Exp $")
private int match(struct magic_set *, struct magic *, uint32_t,
const struct buffer *, size_t, int, int, int, uint16_t *,
- uint16_t *, int *, int *, int *);
+ uint16_t *, int *, int *, int *, int *);
private int mget(struct magic_set *, struct magic *, const struct buffer *,
- const unsigned char *, size_t,
+ const unsigned char *, size_t,
size_t, unsigned int, int, int, int, uint16_t *,
- uint16_t *, int *, int *, int *);
+ uint16_t *, int *, int *, int *, int *);
private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
const struct buffer *, size_t, unsigned int);
private int magiccheck(struct magic_set *, struct magic *);
@@ -67,24 +67,46 @@ private int cvt_16(union VALUETYPE *, const struct magic *);
private int cvt_32(union VALUETYPE *, const struct magic *);
private int cvt_64(union VALUETYPE *, const struct magic *);
-#define OFFSET_OOB(n, o, i) ((n) < (uint32_t)(o) || (i) > ((n) - (o)))
-#define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \
- ((uint64_t)(p)->hq[2]<<40)|((uint64_t)(p)->hq[3]<<32)| \
- ((uint64_t)(p)->hq[4]<<24)|((uint64_t)(p)->hq[5]<<16)| \
- ((uint64_t)(p)->hq[6]<<8)|((uint64_t)(p)->hq[7]))
-#define LE64(p) (((uint64_t)(p)->hq[7]<<56)|((uint64_t)(p)->hq[6]<<48)| \
- ((uint64_t)(p)->hq[5]<<40)|((uint64_t)(p)->hq[4]<<32)| \
- ((uint64_t)(p)->hq[3]<<24)|((uint64_t)(p)->hq[2]<<16)| \
- ((uint64_t)(p)->hq[1]<<8)|((uint64_t)(p)->hq[0]))
-#define LE32(p) (((uint32_t)(p)->hl[3]<<24)|((uint32_t)(p)->hl[2]<<16)| \
- ((uint32_t)(p)->hl[1]<<8)|((uint32_t)(p)->hl[0]))
-#define BE32(p) (((uint32_t)(p)->hl[0]<<24)|((uint32_t)(p)->hl[1]<<16)| \
- ((uint32_t)(p)->hl[2]<<8)|((uint32_t)(p)->hl[3]))
-#define ME32(p) (((uint32_t)(p)->hl[1]<<24)|((uint32_t)(p)->hl[0]<<16)| \
- ((uint32_t)(p)->hl[3]<<8)|((uint32_t)(p)->hl[2]))
-#define BE16(p) (((uint16_t)(p)->hs[0]<<8)|((uint16_t)(p)->hs[1]))
-#define LE16(p) (((uint16_t)(p)->hs[1]<<8)|((uint16_t)(p)->hs[0]))
-#define SEXT(s,v,p) ((s)?(intmax_t)(int##v##_t)(p):(intmax_t)(uint##v##_t)(p))
+#define OFFSET_OOB(n, o, i) ((n) < CAST(uint32_t, (o)) || (i) > ((n) - (o)))
+#define BE64(p) ( \
+ (CAST(uint64_t, (p)->hq[0])<<56)| \
+ (CAST(uint64_t, (p)->hq[1])<<48)| \
+ (CAST(uint64_t, (p)->hq[2])<<40)| \
+ (CAST(uint64_t, (p)->hq[3])<<32)| \
+ (CAST(uint64_t, (p)->hq[4])<<24)| \
+ (CAST(uint64_t, (p)->hq[5])<<16)| \
+ (CAST(uint64_t, (p)->hq[6])<<8)| \
+ (CAST(uint64_t, (p)->hq[7])))
+#define LE64(p) ( \
+ (CAST(uint64_t, (p)->hq[7])<<56)| \
+ (CAST(uint64_t, (p)->hq[6])<<48)| \
+ (CAST(uint64_t, (p)->hq[5])<<40)| \
+ (CAST(uint64_t, (p)->hq[4])<<32)| \
+ (CAST(uint64_t, (p)->hq[3])<<24)| \
+ (CAST(uint64_t, (p)->hq[2])<<16)| \
+ (CAST(uint64_t, (p)->hq[1])<<8)| \
+ (CAST(uint64_t, (p)->hq[0])))
+#define LE32(p) ( \
+ (CAST(uint32_t, (p)->hl[3])<<24)| \
+ (CAST(uint32_t, (p)->hl[2])<<16)| \
+ (CAST(uint32_t, (p)->hl[1])<<8)| \
+ (CAST(uint32_t, (p)->hl[0])))
+#define BE32(p) ( \
+ (CAST(uint32_t, (p)->hl[0])<<24)| \
+ (CAST(uint32_t, (p)->hl[1])<<16)| \
+ (CAST(uint32_t, (p)->hl[2])<<8)| \
+ (CAST(uint32_t, (p)->hl[3])))
+#define ME32(p) ( \
+ (CAST(uint32_t, (p)->hl[1])<<24)| \
+ (CAST(uint32_t, (p)->hl[0])<<16)| \
+ (CAST(uint32_t, (p)->hl[3])<<8)| \
+ (CAST(uint32_t, (p)->hl[2])))
+
+#define BE16(p) ((CAST(uint16_t, (p)->hs[0])<<8)|(CAST(uint16_t, (p)->hs[1])))
+#define LE16(p) ((CAST(uint16_t, (p)->hs[1])<<8)|(CAST(uint16_t, (p)->hs[0])))
+#define SEXT(s,v,p) ((s) ? \
+ CAST(intmax_t, CAST(int##v##_t, p)) : \
+ CAST(intmax_t, CAST(uint##v##_t, p)))
/*
* softmagic - lookup one file in parsed, in-memory copy of database
@@ -111,7 +133,7 @@ file_softmagic(struct magic_set *ms, const struct buffer *b,
for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
if ((rv = match(ms, ml->magic, ml->nmagic, b, 0, mode,
text, 0, indir_count, name_count,
- &printed_something, &need_separator, NULL)) != 0)
+ &printed_something, &need_separator, NULL, NULL)) != 0)
return rv;
return 0;
@@ -167,17 +189,25 @@ private int
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
const struct buffer *b, size_t offset, int mode, int text,
int flip, uint16_t *indir_count, uint16_t *name_count,
- int *printed_something, int *need_separator, int *returnval)
+ int *printed_something, int *need_separator, int *returnval,
+ int *found_match)
{
uint32_t magindex = 0;
unsigned int cont_level = 0;
- int returnvalv = 0, e; /* if a match is found it is set to 1*/
+ int found_matchv = 0; /* if a match is found it is set to 1*/
+ int returnvalv = 0, e;
int firstline = 1; /* a flag to print X\n X\n- X */
struct buffer bb;
int print = (ms->flags & MAGIC_NODESC) == 0;
+ /*
+ * returnval can be 0 if a match is found, but there was no
+ * annotation to be printed.
+ */
if (returnval == NULL)
returnval = &returnvalv;
+ if (found_match == NULL)
+ found_match = &found_matchv;
if (file_check_mem(ms, cont_level) == -1)
return -1;
@@ -206,17 +236,21 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
ms->line = m->lineno;
/* if main entry matches, print it... */
- switch (mget(ms, m, b, bb.fbuf, bb.flen, offset, cont_level,
+ switch (mget(ms, m, b, CAST(const unsigned char *, bb.fbuf),
+ bb.flen, offset, cont_level,
mode, text, flip, indir_count, name_count,
- printed_something, need_separator, returnval)) {
+ printed_something, need_separator, returnval, found_match))
+ {
case -1:
return -1;
case 0:
flush = m->reln != '!';
break;
default:
- if (m->type == FILE_INDIRECT)
+ if (m->type == FILE_INDIRECT) {
+ *found_match = 1;
*returnval = 1;
+ }
switch (magiccheck(ms, m)) {
case -1:
@@ -238,7 +272,11 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
goto flush;
}
- if ((e = handle_annotation(ms, m, firstline)) != 0) {
+ if (*m->desc)
+ *found_match = 1;
+
+ if ((e = handle_annotation(ms, m, firstline)) != 0)
+ {
*need_separator = 1;
*printed_something = 1;
*returnval = 1;
@@ -249,16 +287,16 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* If we are going to print something, we'll need to print
* a blank before we print something else.
*/
- if (*m->desc) {
+ if (print && *m->desc) {
*need_separator = 1;
*printed_something = 1;
+ *returnval = 1;
if (print_sep(ms, firstline) == -1)
return -1;
+ if (mprint(ms, m) == -1)
+ return -1;
}
- if (print && mprint(ms, m) == -1)
- return -1;
-
switch (moffset(ms, m, &bb, &ms->c.li[cont_level].off)) {
case -1:
case 0:
@@ -299,10 +337,11 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
continue;
}
#endif
- switch (mget(ms, m, b, bb.fbuf, bb.flen, offset,
+ switch (mget(ms, m, b, CAST(const unsigned char *,
+ bb.fbuf), bb.flen, offset,
cont_level, mode, text, flip, indir_count,
name_count, printed_something, need_separator,
- returnval)) {
+ returnval, found_match)) {
case -1:
return -1;
case 0:
@@ -311,8 +350,10 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
flush = 1;
break;
default:
- if (m->type == FILE_INDIRECT)
+ if (m->type == FILE_INDIRECT) {
+ *found_match = 1;
*returnval = 1;
+ }
flush = 0;
break;
}
@@ -337,6 +378,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
} else
ms->c.li[cont_level].got_match = 1;
+ if (*m->desc)
+ *found_match = 1;
+
if ((e = handle_annotation(ms, m, firstline))
!= 0) {
*need_separator = 1;
@@ -344,35 +388,36 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
*returnval = 1;
return e;
}
- /*
- * If we are going to print something,
- * make sure that we have a separator first.
- */
- if (*m->desc) {
+ if (print && *m->desc) {
+ /*
+ * This continuation matched. Print
+ * its message, with a blank before it
+ * if the previous item printed and
+ * this item isn't empty.
+ */
+ /*
+ * If we are going to print something,
+ * make sure that we have a separator
+ * first.
+ */
if (!*printed_something) {
*printed_something = 1;
if (print_sep(ms, firstline)
== -1)
return -1;
}
- }
- /*
- * This continuation matched. Print
- * its message, with a blank before it
- * if the previous item printed and
- * this item isn't empty.
- */
- /* space if previous printed */
- if (*need_separator
- && ((m->flag & NOSPACE) == 0)
- && *m->desc) {
- if (print &&
- file_printf(ms, " ") == -1)
- return -1;
+ /* space if previous printed */
+ if (*need_separator
+ && (m->flag & NOSPACE) == 0) {
+ if (file_printf(ms, " ") == -1)
+ return -1;
+ }
+ *returnval = 1;
*need_separator = 0;
+ if (mprint(ms, m) == -1)
+ return -1;
+ *need_separator = 1;
}
- if (print && mprint(ms, m) == -1)
- return -1;
switch (moffset(ms, m, &bb,
&ms->c.li[cont_level].off)) {
@@ -385,9 +430,6 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break;
}
- if (*m->desc)
- *need_separator = 1;
-
/*
* If we see any continuations
* at a higher level,
@@ -400,10 +442,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
}
if (*printed_something) {
firstline = 0;
- if (print)
- *returnval = 1;
}
- if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) {
+ if ((ms->flags & MAGIC_CONTINUE) == 0 && *found_match) {
return *returnval; /* don't keep searching */
}
cont_level = 0;
@@ -460,7 +500,7 @@ varexpand(struct magic_set *ms, char *buf, size_t len, const char *str)
size_t l;
for (sptr = str; (ptr = strstr(sptr, "${")) != NULL;) {
- l = (size_t)(ptr - sptr);
+ l = CAST(size_t, ptr - sptr);
if (l >= len)
return -1;
memcpy(buf, sptr, l);
@@ -526,19 +566,19 @@ mprint(struct magic_set *ms, struct magic *m)
switch (m->type) {
case FILE_BYTE:
- v = file_signextend(ms, m, (uint64_t)p->b);
+ v = file_signextend(ms, m, CAST(uint64_t, p->b));
switch (check_fmt(ms, desc)) {
case -1:
return -1;
case 1:
(void)snprintf(buf, sizeof(buf), "%d",
- (unsigned char)v);
+ CAST(unsigned char, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
if (file_printf(ms, F(ms, desc, "%d"),
- (unsigned char) v) == -1)
+ CAST(unsigned char, v)) == -1)
return -1;
break;
}
@@ -548,19 +588,19 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_SHORT:
case FILE_BESHORT:
case FILE_LESHORT:
- v = file_signextend(ms, m, (uint64_t)p->h);
+ v = file_signextend(ms, m, CAST(uint64_t, p->h));
switch (check_fmt(ms, desc)) {
case -1:
return -1;
case 1:
(void)snprintf(buf, sizeof(buf), "%u",
- (unsigned short)v);
+ CAST(unsigned short, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
if (file_printf(ms, F(ms, desc, "%u"),
- (unsigned short) v) == -1)
+ CAST(unsigned short, v)) == -1)
return -1;
break;
}
@@ -571,17 +611,19 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BELONG:
case FILE_LELONG:
case FILE_MELONG:
- v = file_signextend(ms, m, (uint64_t)p->l);
+ v = file_signextend(ms, m, CAST(uint64_t, p->l));
switch (check_fmt(ms, desc)) {
case -1:
return -1;
case 1:
- (void)snprintf(buf, sizeof(buf), "%u", (uint32_t) v);
+ (void)snprintf(buf, sizeof(buf), "%u",
+ CAST(uint32_t, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
- if (file_printf(ms, F(ms, desc, "%u"), (uint32_t) v) == -1)
+ if (file_printf(ms, F(ms, desc, "%u"),
+ CAST(uint32_t, v)) == -1)
return -1;
break;
}
@@ -597,13 +639,13 @@ mprint(struct magic_set *ms, struct magic *m)
return -1;
case 1:
(void)snprintf(buf, sizeof(buf), "%" INT64_T_FORMAT "u",
- (unsigned long long)v);
+ CAST(unsigned long long, v));
if (file_printf(ms, F(ms, desc, "%s"), buf) == -1)
return -1;
break;
default:
if (file_printf(ms, F(ms, desc, "%" INT64_T_FORMAT "u"),
- (unsigned long long) v) == -1)
+ CAST(unsigned long long, v)) == -1)
return -1;
break;
}
@@ -615,9 +657,9 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BESTRING16:
case FILE_LESTRING16:
if (m->reln == '=' || m->reln == '!') {
- if (file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), m->value.s))
- == -1)
+ if (file_printf(ms, F(ms, desc, "%s"),
+ file_printable(sbuf, sizeof(sbuf), m->value.s,
+ sizeof(m->value.s))) == -1)
return -1;
t = ms->offset + m->vallen;
}
@@ -632,19 +674,20 @@ mprint(struct magic_set *ms, struct magic *m)
if (m->str_flags & STRING_TRIM) {
char *last;
- while (isspace((unsigned char)*str))
+ while (isspace(CAST(unsigned char, *str)))
str++;
last = str;
while (*last)
last++;
--last;
- while (isspace((unsigned char)*last))
+ while (isspace(CAST(unsigned char, *last)))
last--;
*++last = '\0';
}
if (file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), str)) == -1)
+ file_printable(sbuf, sizeof(sbuf), str,
+ sizeof(p->s) - (str - p->s))) == -1)
return -1;
if (m->type == FILE_PSTRING)
@@ -744,13 +787,14 @@ mprint(struct magic_set *ms, struct magic *m)
char *cp;
int rval;
- cp = strndup((const char *)ms->search.s, ms->search.rm_len);
+ cp = strndup(RCAST(const char *, ms->search.s),
+ ms->search.rm_len);
if (cp == NULL) {
file_oomem(ms, ms->search.rm_len);
return -1;
}
rval = file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), cp));
+ file_printable(sbuf, sizeof(sbuf), cp, ms->search.rm_len));
free(cp);
if (rval == -1)
@@ -776,8 +820,9 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset;
break;
case FILE_DER:
- if (file_printf(ms, F(ms, desc, "%s"),
- file_printable(sbuf, sizeof(sbuf), ms->ms_value.s)) == -1)
+ if (file_printf(ms, F(ms, desc, "%s"),
+ file_printable(sbuf, sizeof(sbuf), ms->ms_value.s,
+ sizeof(ms->ms_value.s))) == -1)
return -1;
t = ms->offset;
break;
@@ -785,7 +830,7 @@ mprint(struct magic_set *ms, struct magic *m)
file_magerror(ms, "invalid m->type (%d) in mprint()", m->type);
return -1;
}
- return (int32_t)t;
+ return CAST(int32_t, t);
}
private int
@@ -832,7 +877,8 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
p->s[strcspn(p->s, "\r\n")] = '\0';
o = CAST(uint32_t, (ms->offset + strlen(p->s)));
if (m->type == FILE_PSTRING)
- o += (uint32_t)file_pstring_length_size(m);
+ o += CAST(uint32_t,
+ file_pstring_length_size(m));
}
break;
@@ -898,11 +944,11 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
case FILE_DER:
{
o = der_offs(ms, m, nbytes);
- if (o == -1 || (size_t)o > nbytes) {
+ if (o == -1 || CAST(size_t, o) > nbytes) {
if ((ms->flags & MAGIC_DEBUG) != 0) {
(void)fprintf(stderr,
- "Bad DER offset %d nbytes=%zu",
- o, nbytes);
+ "Bad DER offset %d nbytes=%"
+ SIZE_T_FORMAT "u", o, nbytes);
}
*op = 0;
return 0;
@@ -915,10 +961,10 @@ moffset(struct magic_set *ms, struct magic *m, const struct buffer *b,
break;
}
- if ((size_t)o > nbytes) {
+ if (CAST(size_t, o) > nbytes) {
#if 0
- file_error(ms, 0, "Offset out of range %zu > %zu",
- (size_t)o, nbytes);
+ file_error(ms, 0, "Offset out of range %" SIZE_T_FORMAT
+ "u > %" SIZE_T_FORMAT "u", (size_t)o, nbytes);
#endif
return -1;
}
@@ -988,36 +1034,36 @@ cvt_flip(int type, int flip)
return type;
}
}
-#define DO_CVT(fld, cast) \
+#define DO_CVT(fld, type) \
if (m->num_mask) \
switch (m->mask_op & FILE_OPS_MASK) { \
case FILE_OPAND: \
- p->fld &= cast m->num_mask; \
+ p->fld &= CAST(type, m->num_mask); \
break; \
case FILE_OPOR: \
- p->fld |= cast m->num_mask; \
+ p->fld |= CAST(type, m->num_mask); \
break; \
case FILE_OPXOR: \
- p->fld ^= cast m->num_mask; \
+ p->fld ^= CAST(type, m->num_mask); \
break; \
case FILE_OPADD: \
- p->fld += cast m->num_mask; \
+ p->fld += CAST(type, m->num_mask); \
break; \
case FILE_OPMINUS: \
- p->fld -= cast m->num_mask; \
+ p->fld -= CAST(type, m->num_mask); \
break; \
case FILE_OPMULTIPLY: \
- p->fld *= cast m->num_mask; \
+ p->fld *= CAST(type, m->num_mask); \
break; \
case FILE_OPDIVIDE: \
- if (cast m->num_mask == 0) \
+ if (CAST(type, m->num_mask) == 0) \
return -1; \
- p->fld /= cast m->num_mask; \
+ p->fld /= CAST(type, m->num_mask); \
break; \
case FILE_OPMODULO: \
- if (cast m->num_mask == 0) \
+ if (CAST(type, m->num_mask) == 0) \
return -1; \
- p->fld %= cast m->num_mask; \
+ p->fld %= CAST(type, m->num_mask); \
break; \
} \
if (m->mask_op & FILE_OPINVERSE) \
@@ -1026,61 +1072,61 @@ cvt_flip(int type, int flip)
private int
cvt_8(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(b, (uint8_t));
+ DO_CVT(b, uint8_t);
return 0;
}
private int
cvt_16(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(h, (uint16_t));
+ DO_CVT(h, uint16_t);
return 0;
}
private int
cvt_32(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(l, (uint32_t));
+ DO_CVT(l, uint32_t);
return 0;
}
private int
cvt_64(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT(q, (uint64_t));
+ DO_CVT(q, uint64_t);
return 0;
}
-#define DO_CVT2(fld, cast) \
+#define DO_CVT2(fld, type) \
if (m->num_mask) \
switch (m->mask_op & FILE_OPS_MASK) { \
case FILE_OPADD: \
- p->fld += cast m->num_mask; \
+ p->fld += CAST(type, m->num_mask); \
break; \
case FILE_OPMINUS: \
- p->fld -= cast m->num_mask; \
+ p->fld -= CAST(type, m->num_mask); \
break; \
case FILE_OPMULTIPLY: \
- p->fld *= cast m->num_mask; \
+ p->fld *= CAST(type, m->num_mask); \
break; \
case FILE_OPDIVIDE: \
- if (cast m->num_mask == 0) \
+ if (CAST(type, m->num_mask) == 0) \
return -1; \
- p->fld /= cast m->num_mask; \
+ p->fld /= CAST(type, m->num_mask); \
break; \
} \
private int
cvt_float(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT2(f, (float));
+ DO_CVT2(f, float);
return 0;
}
private int
cvt_double(union VALUETYPE *p, const struct magic *m)
{
- DO_CVT2(d, (double));
+ DO_CVT2(d, double);
return 0;
}
@@ -1136,7 +1182,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
* string by p->s, so we need to deduct sz.
* Because we can use one of the bytes of the length
* after we shifted as NUL termination.
- */
+ */
len = sz;
}
while (len--)
@@ -1145,14 +1191,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
return 1;
}
case FILE_BESHORT:
- p->h = (short)BE16(p);
+ p->h = CAST(short, BE16(p));
if (cvt_16(p, m) == -1)
goto out;
return 1;
case FILE_BELONG:
case FILE_BEDATE:
case FILE_BELDATE:
- p->l = (int32_t)BE32(p);
+ p->l = CAST(int32_t, BE32(p));
if (cvt_32(p, m) == -1)
goto out;
return 1;
@@ -1160,19 +1206,19 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
case FILE_BEQDATE:
case FILE_BEQLDATE:
case FILE_BEQWDATE:
- p->q = (uint64_t)BE64(p);
+ p->q = CAST(uint64_t, BE64(p));
if (cvt_64(p, m) == -1)
goto out;
return 1;
case FILE_LESHORT:
- p->h = (short)LE16(p);
+ p->h = CAST(short, LE16(p));
if (cvt_16(p, m) == -1)
goto out;
return 1;
case FILE_LELONG:
case FILE_LEDATE:
case FILE_LELDATE:
- p->l = (int32_t)LE32(p);
+ p->l = CAST(int32_t, LE32(p));
if (cvt_32(p, m) == -1)
goto out;
return 1;
@@ -1180,14 +1226,14 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
case FILE_LEQDATE:
case FILE_LEQLDATE:
case FILE_LEQWDATE:
- p->q = (uint64_t)LE64(p);
+ p->q = CAST(uint64_t, LE64(p));
if (cvt_64(p, m) == -1)
goto out;
return 1;
case FILE_MELONG:
case FILE_MEDATE:
case FILE_MELDATE:
- p->l = (int32_t)ME32(p);
+ p->l = CAST(int32_t, ME32(p));
if (cvt_32(p, m) == -1)
goto out;
return 1;
@@ -1210,7 +1256,7 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
goto out;
return 1;
case FILE_BEDOUBLE:
- p->q = BE64(p);
+ p->q = BE64(p);
if (cvt_double(p, m) == -1)
goto out;
return 1;
@@ -1301,9 +1347,11 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
|| (b = CAST(const char *,
memchr(c, '\r', CAST(size_t, (end - c))))));
lines--, b++) {
- last = b;
if (b < end - 1 && b[0] == '\r' && b[1] == '\n')
b++;
+ if (b < end - 1 && b[0] == '\n')
+ b++;
+ last = b;
}
if (lines)
last = end;
@@ -1366,7 +1414,7 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
* might even cause problems
*/
if (nbytes < sizeof(*p))
- (void)memset(((char *)(void *)p) + nbytes, '\0',
+ (void)memset(RCAST(char *, RCAST(void *, p)) + nbytes, '\0',
sizeof(*p) - nbytes);
return 0;
}
@@ -1407,7 +1455,7 @@ do_ops(struct magic *m, intmax_t lhs, intmax_t off)
if (m->in_op & FILE_OPINVERSE)
offset = ~offset;
- return (uint32_t)offset;
+ return CAST(uint32_t, offset);
}
private int
@@ -1428,14 +1476,14 @@ msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
return -1;
if (o != 0) {
// Not yet!
- file_magerror(ms, "non zero offset %zu at"
- " level %u", o, cont_level);
+ file_magerror(ms, "non zero offset %" SIZE_T_FORMAT
+ "u at level %u", o, cont_level);
return -1;
}
- if ((size_t)-m->offset > b->elen)
+ if (CAST(size_t, -m->offset) > b->elen)
return -1;
buffer_init(bb, -1, b->ebuf, b->elen);
- ms->eoffset = ms->offset = b->elen + m->offset;
+ ms->eoffset = ms->offset = CAST(int32_t, b->elen + m->offset);
} else {
if (cont_level == 0) {
normal:
@@ -1448,7 +1496,8 @@ msetoffset(struct magic_set *ms, struct magic *m, struct buffer *bb,
}
}
if ((ms->flags & MAGIC_DEBUG) != 0) {
- fprintf(stderr, "bb=[%p,%zu], %d [b=%p,%zu], [o=%#x, c=%d]\n",
+ fprintf(stderr, "bb=[%p,%" SIZE_T_FORMAT "u], %d [b=%p,%"
+ SIZE_T_FORMAT "u], [o=%#x, c=%d]\n",
bb->fbuf, bb->flen, ms->offset, b->fbuf, b->flen,
m->offset, cont_level);
}
@@ -1459,7 +1508,8 @@ private int
mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
const unsigned char *s, size_t nbytes, size_t o, unsigned int cont_level,
int mode, int text, int flip, uint16_t *indir_count, uint16_t *name_count,
- int *printed_something, int *need_separator, int *returnval)
+ int *printed_something, int *need_separator, int *returnval,
+ int *found_match)
{
uint32_t offset = ms->offset;
struct buffer bb;
@@ -1484,8 +1534,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
- if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
- (uint32_t)nbytes, m) == -1)
+ if (mcopy(ms, p, m->type, m->flag & INDIR, s,
+ CAST(uint32_t, offset + o), CAST(uint32_t, nbytes), m) == -1)
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
@@ -1494,7 +1544,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
"u, il=%hu, nc=%hu)\n",
m->type, m->flag, offset, o, nbytes,
*indir_count, *name_count);
- mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
+ mdebug(offset, RCAST(char *, RCAST(void *, p)),
+ sizeof(union VALUETYPE));
#ifndef COMPILE_ONLY
file_mdump(m);
#endif
@@ -1505,40 +1556,58 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
const int sgn = m->in_op & FILE_OPSIGNED;
if (m->in_op & FILE_OPINDIRECT) {
const union VALUETYPE *q = CAST(const union VALUETYPE *,
- ((const void *)(s + offset + off)));
- if (OFFSET_OOB(nbytes, offset + off, sizeof(*q)))
- return 0;
+ RCAST(const void *, s + offset + off));
switch (cvt_flip(m->in_type, flip)) {
case FILE_BYTE:
+ if (OFFSET_OOB(nbytes, offset + off, 1))
+ return 0;
off = SEXT(sgn,8,q->b);
break;
case FILE_SHORT:
+ if (OFFSET_OOB(nbytes, offset + off, 2))
+ return 0;
off = SEXT(sgn,16,q->h);
break;
case FILE_BESHORT:
+ if (OFFSET_OOB(nbytes, offset + off, 2))
+ return 0;
off = SEXT(sgn,16,BE16(q));
break;
case FILE_LESHORT:
+ if (OFFSET_OOB(nbytes, offset + off, 2))
+ return 0;
off = SEXT(sgn,16,LE16(q));
break;
case FILE_LONG:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,q->l);
break;
case FILE_BELONG:
case FILE_BEID3:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,BE32(q));
break;
case FILE_LEID3:
case FILE_LELONG:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,LE32(q));
break;
case FILE_MELONG:
+ if (OFFSET_OOB(nbytes, offset + off, 4))
+ return 0;
off = SEXT(sgn,32,ME32(q));
break;
case FILE_BEQUAD:
+ if (OFFSET_OOB(nbytes, offset + off, 8))
+ return 0;
off = SEXT(sgn,64,BE64(q));
break;
case FILE_LEQUAD:
+ if (OFFSET_OOB(nbytes, offset + off, 8))
+ return 0;
off = SEXT(sgn,64,LE64(q));
break;
default:
@@ -1574,7 +1643,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 0;
lhs = BE32(p);
if (in_type == FILE_BEID3)
- lhs = cvt_id3(ms, (uint32_t)lhs);
+ lhs = cvt_id3(ms, CAST(uint32_t, lhs));
offset = do_ops(m, SEXT(sgn,32,lhs), off);
break;
case FILE_LELONG:
@@ -1583,7 +1652,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
return 0;
lhs = LE32(p);
if (in_type == FILE_LEID3)
- lhs = cvt_id3(ms, (uint32_t)lhs);
+ lhs = cvt_id3(ms, CAST(uint32_t, lhs));
offset = do_ops(m, SEXT(sgn,32,lhs), off);
break;
case FILE_MELONG:
@@ -1626,7 +1695,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
ms->offset = offset;
if ((ms->flags & MAGIC_DEBUG) != 0) {
- mdebug(offset, (char *)(void *)p,
+ mdebug(offset, RCAST(char *, RCAST(void *, p)),
sizeof(union VALUETYPE));
#ifndef COMPILE_ONLY
file_mdump(m);
@@ -1714,7 +1783,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
if (rv == 1) {
if ((ms->flags & MAGIC_NODESC) == 0 &&
- file_printf(ms, F(ms, m->desc, "%u"), offset) == -1) {
+ file_printf(ms, F(ms, m->desc, "%u"), offset) == -1)
+ {
free(rbuf);
return -1;
}
@@ -1744,7 +1814,8 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
*need_separator = 0;
rv = match(ms, ml.magic, ml.nmagic, b, offset + o,
mode, text, flip, indir_count, name_count,
- printed_something, need_separator, returnval);
+ printed_something, need_separator, returnval, found_match);
+ (*name_count)--;
if (rv != 1)
*need_separator = oneed_separator;
return rv;
@@ -1775,8 +1846,8 @@ file_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags)
* the ctype functions will work correctly without extra
* casting.
*/
- const unsigned char *a = (const unsigned char *)s1;
- const unsigned char *b = (const unsigned char *)s2;
+ const unsigned char *a = RCAST(const unsigned char *, s1);
+ const unsigned char *b = RCAST(const unsigned char *, s2);
const unsigned char *eb = b + len;
uint64_t v;
@@ -1971,13 +2042,15 @@ magiccheck(struct magic_set *ms, struct magic *m)
case FILE_STRING:
case FILE_PSTRING:
l = 0;
- v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
+ v = file_strncmp(m->value.s, p->s, CAST(size_t, m->vallen),
+ m->str_flags);
break;
case FILE_BESTRING16:
case FILE_LESTRING16:
l = 0;
- v = file_strncmp16(m->value.s, p->s, (size_t)m->vallen, m->str_flags);
+ v = file_strncmp16(m->value.s, p->s, CAST(size_t, m->vallen),
+ m->str_flags);
break;
case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */
@@ -2019,7 +2092,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
if (rc) {
file_regerror(&rx, rc, ms);
- v = (uint64_t)-1;
+ v = CAST(uint64_t, -1);
} else {
regmatch_t pmatch;
size_t slen = ms->search.s_len;
@@ -2040,15 +2113,15 @@ magiccheck(struct magic_set *ms, struct magic *m)
search = CCAST(char *, "");
copy = NULL;
}
- rc = file_regexec(&rx, (const char *)search,
+ rc = file_regexec(&rx, RCAST(const char *, search),
1, &pmatch, 0);
free(copy);
switch (rc) {
case 0:
- ms->search.s += (int)pmatch.rm_so;
- ms->search.offset += (size_t)pmatch.rm_so;
- ms->search.rm_len =
- (size_t)(pmatch.rm_eo - pmatch.rm_so);
+ ms->search.s += CAST(int, pmatch.rm_so);
+ ms->search.offset += CAST(size_t, pmatch.rm_so);
+ ms->search.rm_len = CAST(size_t,
+ pmatch.rm_eo - pmatch.rm_so);
v = 0;
break;
@@ -2058,12 +2131,12 @@ magiccheck(struct magic_set *ms, struct magic *m)
default:
file_regerror(&rx, rc, ms);
- v = (uint64_t)-1;
+ v = CAST(uint64_t, -1);
break;
}
}
file_regfree(&rx);
- if (v == (uint64_t)-1)
+ if (v == CAST(uint64_t, -1))
return -1;
break;
}
@@ -2092,7 +2165,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
case 'x':
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
- "u == *any* = 1\n", (unsigned long long)v);
+ "u == *any* = 1\n", CAST(unsigned long long, v));
matched = 1;
break;
@@ -2100,16 +2173,18 @@ magiccheck(struct magic_set *ms, struct magic *m)
matched = v != l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT "u != %"
- INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
- (unsigned long long)l, matched);
+ INT64_T_FORMAT "u = %d\n",
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
break;
case '=':
matched = v == l;
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT "u == %"
- INT64_T_FORMAT "u = %d\n", (unsigned long long)v,
- (unsigned long long)l, matched);
+ INT64_T_FORMAT "u = %d\n",
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
break;
case '>':
@@ -2118,15 +2193,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"u > %" INT64_T_FORMAT "u = %d\n",
- (unsigned long long)v,
- (unsigned long long)l, matched);
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
}
else {
- matched = (int64_t) v > (int64_t) l;
+ matched = CAST(int64_t, v) > CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"d > %" INT64_T_FORMAT "d = %d\n",
- (long long)v, (long long)l, matched);
+ CAST(long long, v),
+ CAST(long long, l), matched);
}
break;
@@ -2136,15 +2212,16 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"u < %" INT64_T_FORMAT "u = %d\n",
- (unsigned long long)v,
- (unsigned long long)l, matched);
+ CAST(unsigned long long, v),
+ CAST(unsigned long long, l), matched);
}
else {
- matched = (int64_t) v < (int64_t) l;
+ matched = CAST(int64_t, v) < CAST(int64_t, l);
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "%" INT64_T_FORMAT
"d < %" INT64_T_FORMAT "d = %d\n",
- (long long)v, (long long)l, matched);
+ CAST(long long, v),
+ CAST(long long, l), matched);
}
break;
@@ -2153,8 +2230,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
INT64_T_FORMAT "x) == %" INT64_T_FORMAT
- "x) = %d\n", (unsigned long long)v,
- (unsigned long long)l, (unsigned long long)l,
+ "x) = %d\n", CAST(unsigned long long, v),
+ CAST(unsigned long long, l),
+ CAST(unsigned long long, l),
matched);
break;
@@ -2163,9 +2241,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
if ((ms->flags & MAGIC_DEBUG) != 0)
(void) fprintf(stderr, "((%" INT64_T_FORMAT "x & %"
INT64_T_FORMAT "x) != %" INT64_T_FORMAT
- "x) = %d\n", (unsigned long long)v,
- (unsigned long long)l, (unsigned long long)l,
- matched);
+ "x) = %d\n", CAST(unsigned long long, v),
+ CAST(unsigned long long, l),
+ CAST(unsigned long long, l), matched);
break;
default:
@@ -2181,14 +2259,14 @@ private int
handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
{
if ((ms->flags & MAGIC_APPLE) && m->apple[0]) {
- if (!firstline && file_printf(ms, "\n- ") == -1)
+ if (print_sep(ms, firstline) == -1)
return -1;
if (file_printf(ms, "%.8s", m->apple) == -1)
return -1;
return 1;
}
if ((ms->flags & MAGIC_EXTENSION) && m->ext[0]) {
- if (!firstline && file_printf(ms, "\n- ") == -1)
+ if (print_sep(ms, firstline) == -1)
return -1;
if (file_printf(ms, "%s", m->ext) == -1)
return -1;
@@ -2197,7 +2275,7 @@ handle_annotation(struct magic_set *ms, struct magic *m, int firstline)
if ((ms->flags & MAGIC_MIME_TYPE) && m->mimetype[0]) {
char buf[1024];
const char *p;
- if (!firstline && file_printf(ms, "\n- ") == -1)
+ if (print_sep(ms, firstline) == -1)
return -1;
if (varexpand(ms, buf, sizeof(buf), m->mimetype) == -1)
p = m->mimetype;
diff --git a/libmagic/src/main/cpp/file/vasprintf.c b/libmagic/src/main/cpp/file/vasprintf.c
index ad1d316..c87465b 100644
--- a/libmagic/src/main/cpp/file/vasprintf.c
+++ b/libmagic/src/main/cpp/file/vasprintf.c
@@ -2,7 +2,7 @@
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 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 THE AUTHOR AND 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
@@ -51,7 +51,7 @@ 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. The name of the author may not be used to
endorse or promote products derived from this software without specific
-prior written permission.
+prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -108,7 +108,7 @@ you use strange formats.
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: vasprintf.c,v 1.14 2017/08/13 00:21:47 christos Exp $")
+FILE_RCSID("@(#)$File: vasprintf.c,v 1.16 2018/10/01 18:45:39 christos Exp $")
#endif /* lint */
#include
@@ -116,12 +116,8 @@ FILE_RCSID("@(#)$File: vasprintf.c,v 1.14 2017/08/13 00:21:47 christos Exp $")
#include
#include
#include
-#ifdef HAVE_LIMITS_H
#include
-#endif
-#ifdef HAVE_STDDEF_H
#include
-#endif
#define ALLOC_CHUNK 2048
#define ALLOC_SECURITY_MARGIN 1024 /* big value because some platforms have very big 'G' exponent */
diff --git a/libmagic/src/test/java/com/hzy/libmagic/ExampleUnitTest.java b/libmagic/src/test/java/com/hzy/libmagic/ExampleUnitTest.java
deleted file mode 100644
index 9f85594..0000000
--- a/libmagic/src/test/java/com/hzy/libmagic/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.hzy.libmagic;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file